У меня проблемы с MPI_Allgather в части большого программного обеспечения.
Следующая функция получает двойной и связанный флаг, который отличается на каждом узле, затем предполагается, что функция найдет глобально минимальный двойной и установит все узлы на соответствующие значения.
void set_dt_to_global_min (double *dt, int *flag) {
int ierr, size;
ierr = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size == 1)
return;
typedef struct DT_FLAG_ {
double dt;
int flag;
} DT_FLAG;
DT_FLAG local;
DT_FLAG *gathered = (DT_FLAG *) malloc(size * sizeof(*gathered));
local.dt = *dt;
local.flag = *flag;
MPI_Allgather(&local, sizeof(DT_FLAG), MPI_BYTE, gathered, sizeof(DT_FLAG), MPI_BYTE, MPI_COMM_WORLD);
int i, imin;
for (imin = 0, i = 1; i < size; ++i) {
if (gathered[imin].dt > gathered[i].dt) {
imin = i;
}
}
*dt = gathered[imin].dt;
*flag = gathered[imin].flag;
free(gathered);
}
Я выполняю это на 6 узлах в настоящее время и обнаружил, что следующая ошибка возникает только на Узле 5 (который имеет наименьшее значение dt):
- истинное значение
gathered[0]
заменяется на gathered[2]
- истинное значение
gathered[1]
заменяется на gathered[3]
Я подумал, что, возможно, это как-то связано с MPI_COMM_WORLD какпотенциально существует вызов MPI_Comm_Split ();однако, пока, я не понимаю эту часть кода.
У кого-нибудь есть идеи?
- РЕДАКТИРОВАТЬ: Обновлен вопрос, чтобы отразить, что нам действительно нужно удерживать флаг, который также связан с dt
- это означает @suszterpattпредложение отлично подходит для моего первоначального вопроса, но на самом деле не подойдет (я не думаю) для этого.