Невозможно отменить запросы MPI после тестирования

0

Я пытаюсь создать симуляцию с помощью библиотеки boost, но столкнулся с проблемой асинхронной связи процессов. В нашем случае есть два процесса, которые отправляют/принимают сообщения от/друг к другу (используя команды isend и ireceive). Если я жду, когда все команды отправки/получения завершатся, тогда все будет в порядке. Итак, это мой рабочий код:

boost::mpi::communicator* comm;
// Initialize MPI and etc.
...

std::vector<boost::mpi::request> sendRequests;
std::vector<boost::mpi::request> receiveRequests;

for(int i=0; i< 10; i++){
    receiveRequests.push_back(comm->irecv(0, 3000, receivedMessage));
    sendRequests.push_back(comm->isend(1, 3000, sentMessage));

    boost::mpi::wait_all(receiveRequests.begin(), receiveRequests.end());
    receiveRequests.clear();
}

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

boost::mpi::communicator* comm;
// Initialize MPI and etc.
...

std::vector<boost::mpi::request> sendRequests;
std::vector<boost::mpi::request> receiveRequests;

for(int i=0; i< 10; i++){
    receiveRequests.push_back(comm->irecv(0, 3000, receivedMessage));
    sendRequests.push_back(comm->isend(1, 3000, sentMessage));

    vector<boost::mpi::request>::iterator it = receiveRequests.begin();
    while(it != receiveRequests.end()){
        if(!((*it).test()))
            (*it).cancel();     
        receiveRequests.erase(it);
    }
}

Теперь моя программа выходит из строя, и я получаю эту ошибку после первой итерации цикла:

terminate called after throwing an instance of 'std::length_error'
what():  vector::_M_fill_insert
terminate called after throwing an instance of 'std::bad_alloc'
what():  std::bad_alloc
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::mpi::exception> >'
what():  MPI_Test: Message truncated, error stack:
PMPI_Test(168)....................: MPI_Test(request=0x13bba24, flag=0x7fff081a7bd4, status=0x7fff081a7ba0) failed
MPIR_Test_impl(63)................: 
MPIDI_CH3U_Receive_data_found(129): Message from rank 0 and tag 3000 truncated; 670 bytes received but buffer size is 577

Итак, я хотел бы знать, как разрешить эту ошибку.

  • 0
    Здесь недостаточно кода, чтобы воспроизвести ошибку, поэтому все, что вы получите, - это догадки. Можно сказать, что согласно сообщению об ошибке, проблема не отменяется, она тестируется. В частности, похоже, что вы отправляете несколько получений (из разных рангов? Кто знает?) С одним и тем же тегом (я полагаю), но разной длины (кто-то отправил 670 байт, но вы ожидали что-то 577 байт). Таким образом, когда происходит тест, этот прием выполняется и терпит неудачу. По какой-то причине в исходном коде, возможно, из-за повышенной синхронизации (кто может сказать?) Этого не произошло.
  • 0
    Я пытался отправлять запросы с разными тегами, но результат тот же. На каждой итерации цикла процессы отправляют друг другу сообщения, которые имеют разные теги, но не работают. Как вы сказали, похоже, ошибка в тестовой функции. Даже если я не отменяю запрос (а просто проверяю), я все равно получаю ту же ошибку. Я хотел бы предоставить еще немного кода, но я не знаю, что я могу поставить. Потому что просто использование метода теста вместо ожидания выглядит причиной ошибки. И у меня не так много кода в дополнение к этим строкам. Я имею в виду, что они не связаны с MPI.
Теги:
mpi
asynchronous
boost
communication

2 ответа

0
Лучший ответ

Наконец, я понял это. Это было просто из-за состояния гонки между методами тестирования и отмены. Поскольку во время выполнения существует сотни запросов на сообщения, иногда возникает такая ситуация. После тестирования запроса программа не может отменить ее, потому что она только что закончилась (после метода тестирования, но до метода отмены). Вот почему это происходит нерегулярно. Итак, мне пришлось изменить способ, что я хотел сделать, и удалить метод отмены.

1

Откуда it? Это нигде

Обратите внимание, что push_back может перераспределять и это делает недействительными любые ожидающие итераторы.

Также обратите внимание, что вам необходимо условно увеличить it если вы сделали удаление. Типичный шаблон

 it = receiveRequests.erase(it);

Обновление. Я вижу, что вы добавили информацию на вопрос. Вероятно, это должно быть:

vector<boost::mpi::request>::iterator it = receiveRequests.begin();
while(it != receiveRequests.end()){
    if(!((*it).test()))
        (*it).cancel();     
    it = receiveRequests.erase(it);
}

Я не уверен, почему вы всегда удаляете каждый запрос на получение. Я предполагаю, что намерение

  • 0
    Спасибо за Ваш ответ. Я исправил приведенный выше код и попытался увеличить итератор, как вы сказали. Теперь он работает недетерминированно. Иногда я получаю ту же ошибку на первой итерации, иногда на 3-й и т. Д. И иногда я никогда не получаю эту ошибку, и программа завершается, как я ожидал.
  • 1
    Вы увеличиваете итератор в другом месте? Это не должно быть увеличено , если вы удалили элемент. Кроме того, убедитесь, что вектор не может перераспределиться (см. Правила аннулирования итераторов ).
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню