Я передаю большие векторы между процессами для численного моделирования. Все работает нормально до определенного временного шага. Я не получаю ошибок, но выходное решение явно неверно.Общая проблема связи MPI
Я отлаживаю довольно долгое время, и мое предположение заключается в том, что в сообщении MPI есть ошибка.
Связь часть моего кода выглядит следующим образом:
MPI_Request req;
for(int j=0;j<numProcs;j++){
if(j!=myId){
tag=0;
sizeToSend=toProc[j].size();
MPI_Isend(&sizeToSend, 1, MPI_LONG_LONG, j, tag, MPI_COMM_WORLD,&req);
MPI_Request_free(&req);
}
}
for(int j=0;j<numProcs;j++){
if(j!=myId){
tag=0;
MPI_Recv(&sizeToReceive[j], 1, MPI_LONG_LONG, j, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
for(int j=0;j<numProcs;j++){
if(j!=myId){
if(toProc[j].size()>0){
tag=1;
MPI_Isend(&toProc[j][0], toProc[j].size(), MPI_LONG_LONG, j, tag, MPI_COMM_WORLD,&req);
MPI_Request_free(&req);
}
}
}
for(int j=0;j<numProcs;j++){
if(j!=myId){
if(sizeToReceive[j]>0){
receiveBuffer.resize(sizeToReceive[j]);
tag=1;
MPI_Recv(&receiveBuffer[0], sizeToReceive[j], MPI_LONG_LONG, j, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(int k=0;k<sizeToReceive[j];k++){
domain.field[receiveBuffer[k]]=1;
}
receiveBuffer.clear();
}
}
}
MPI_Barrier(MPI_COMM_WORLD);
for(int j=0;j<toProc.size();j++){
toProc[j].clear();
}
Переменная numProcs
является ИНТ, содержащий число процессов, myId
является INT, содержащий ранг процессов, tag
является INT, domain.field
является a vector<char>
. Другие необходимые переменные определены следующим образом:
vector<vector <long long> > toProc;
toProc.resize(numProcs);
long long sizeToReceive[numProcs];
long long sizeToSend=0;
vector<long long> receiveBuffer;
То, что я пытаюсь сделать в коде выше, чтобы отправить векторы toProc[j]
для обработки с id==j for j=0,...,numProcs-1, j!=myId
на каждом процессе. Для этого я отправляю и получаю размеры этих векторов в первых двух циклах for-loops и отправляю и получаю фактические данные в 3-м и 4-м циклах. Я использую Isend, потому что я, очевидно, хочу, чтобы эти вызовы были неблокирующими.
Значения в toProc[j]
- это индексы, которые должны быть установлены в поле vector domain.field в процессе j (каждый процесс имеет свое собственное доменное поле).
Мой вопрос: Вы видите какой-либо потенциал для неожиданного поведения при использовании политики Isend-Recv.
Я не вижу немедленной проблемы, кроме того, возможно, рассылает слишком много текущих запросов, но, похоже, вы могли бы значительно упростить и ускорить всю операцию с помощью MPI_Alltoall и MPI_Alltoallv. – Zulan
Спасибо за предложение, я попытаюсь реализовать то же поведение, используя 'MPI_Alltoall', сколько запросов вы считаете слишком много? Ошибка также возникает, если я использую только 4 процесса, может быть, это уже слишком много? – Jonas
Кажется, я упустил из виду довольно очевидную проблему, пожалуйста, см. Мой ответ. – Zulan