У меня есть реализация MPI в основном для построения сетки на основе IDW2 для набора точек с малой выборкой. Я разделил работу следующим образом:
- Все узлы читают все данные, последний узел не нужен, но что угодно.
Узел 0 берет каждую точку данных и отправляет узлам 1 ... N-1 следующий код:
int nodes_in_play = NNodes-2;
for(int i=0;i < data_size;i++)
{
int dest = (i%nodes_in_play)+1;
//printf("Point %d of %d going to %d\n",i+1,data_size,dest);
Error = MPI_Send(las_points[i],3,MPI_DOUBLE,dest,PIPE_MSG,MPI_COMM_WORLD);
if(Error != MPI_SUCCESS) break;
}
Узлы 1 ... N-1 выполняют оценки на основе IDW
<br>
for(int i=0;i<=data_size-nodes_in_play;i+=nodes_in_play)
{
Error = MPI_Recv(test_point,3,MPI_DOUBLE,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
if(status.MPI_TAG == END_MSG) break;
... IDW2 code
Error = MPI_Send(&zdiff,1,MPI_DOUBLE,NNodes-1,PIPE_MSG,MPI_COMM_WORLD);
}
Узел N получает и сериализует в выходной файл
Это прекрасно работает для 3 узлов, но при большем количестве узлов цикл IDW отключается некоторыми из-за хитрых границ цикла, и весь цикл застревает. Что было бы простым способом запустить процессы приема .. процесса .. отправки в промежуточных узлах. Я ищу изящную линию петли.
Что я сделал:
Вопреки моему мнению, я добавил цикл while (1) в промежуточные узлы с условием выхода, если получено сообщение с END_TAG. Node0 отправляет сообщение END_TAG всем промежуточным узлам, как только все точки отправлены.