Использование MPI_Wait перед новым MPI_Isend - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь использовать MPI_Wait для блокировки MPI_Isend, который может быть вызван или не был вызван ранее, но, похоже, он не блокирует следующий MPI_Isend.

В основном, если был вызван MPI_Isendдо и не было получено, тогда я хочу подождать, пока оно не будет получено.И после этого вызовите новый MPI_Isend.Каждый процесс должен всегда проверять входящие сообщения и получать их динамически.

for (time_stamp=0; time_stamp<time_max; time_stamp++) { // for each time stamp

    // Probe for incoming particles from any process
    MPI_Iprobe(MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &flag, &statRec);

    // Receive particles from a process
    if(flag){
        std::cout << "Recieved from rank: " << statRec.MPI_SOURCE <<  "\n";
        int recCount{};
        MPI_Get_count(&statRec, MPI_Particle, &recCount);
        Particle *recbuf = new Particle[recCount];
        MPI_Recv(recbuf, recCount, MPI_Particle, statRec.MPI_SOURCE, statRec.MPI_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        for(int i=0; i<recCount; i++)
            Particles.emplace_back(recbuf[i]);

        delete[] recbuf;
    }

    int n = (int)Particles.size(), totalp = 0;
    MPI_Reduce(&n, &totalp,  1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
    if(rank == root)
        std::cout << "Total particles "  << totalp << "\n";

    /* Do particle operations, put them in sendlists
       and delete them from this ranks own particle list.... */

    // Send to another process
    if(!sendParticles.empty()) {
        MPI_Wait(&req, MPI_STATUS_IGNORE);
        std::cout << "Sending from rank " << rank << "... \n" ;
        delete[] sendBuf;
        sendcount = static_cast<int>(sendParticles.size());
        sendBuf = new Particle[sendcount];
        for(int i=0; i<sendParticles.size(); i++)
            sendBup[i] = sendParticles[i];

        MPI_Isend(sendBuf, sendcount, MPI_Particle, some_other_rank, 0, MPI_COMM_WORLD, &req);
    }
}

Вывод:
Всего частиц 1000
Отправка с ранга 1 ...
Отправка с ранга 0 ...
Всего частиц 998
Отправка с ранга 1...
Отправка из ранга 0 ...
Получена из ранга: 1
Всего частиц 994
Отправка из ранга 1 ...
Получена из ранга: 0
Отправка изранг 0 ...
Получено из ранга: 1
Всего частиц 993
Отправлено из ранга 0 ...
Получено из ранга: 1
Всего частиц 993
Отправлено из ранга 1...
Отправка с ранга 0 ...

Как видите, он пытается отправить два раза подряд для обоих процессов, игнорируя MPI_Wait.Кажется, что он все время уменьшается до общего количества частиц, я думаю, что некоторые теряются, поскольку он перезаписывает sendbuffer, потому что он не ждет.

(Внесены некоторые изменения в код, чтобы сделать его более читабельным)

1 Ответ

0 голосов
/ 22 мая 2018

Если вы позвоните MPI_Wait() по запросу, поступившему от предыдущего MPI_ISend(), то он будет блокироваться до тех пор, пока буфер отправки не может быть использован повторно.

С очень простой точки зрения, он будетнемедленно вернитесь, если сообщение достаточно короткое, и повесьте, пока не будет отправлено соответствующее сообщение.( достаточно короткий зависит от вашей библиотеки MPI, вашего межсоединения и других факторов. Обратите внимание, что вы никогда не должны принимать как должное, что MPI_Wait() немедленно вернется с небольшими сообщениями).

Ваше описание предлагает вамнеобходимо заменить MPI_Isend() на MPI_Issend().

Обратите внимание, что стандарт только мандаты MPI_Wait() возвращает, когда отправляется соответствующий прием, поэтому, строго говоря, он может вернуться до того, как сообщение будет полностью получено удаленным узлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...