MPI - усечение сообщения в MPI_Recv - PullRequest
3 голосов
/ 19 декабря 2011

У меня проблемы в одном проекте, связанном с разработкой MPI.Я работаю над реализацией алгоритма синтаксического анализа РНК с использованием MPI, в котором я начал анализ входной строки на основе некоторых правил синтаксического анализа и таблицы синтаксического анализа (содержит различные состояния и связанные действия) с главным узлом.В таблице синтаксического анализа есть несколько действий для каждого состояния, которые могут выполняться параллельно.Итак, я должен распределить эти действия между различными процессами.Для этого я отправляю текущее состояние и информацию о синтаксическом анализе (текущий стек синтаксического анализа) узлам, используя отдельный поток для получения действий от других узлов, в то время как основной поток занят анализом на основе полученных действий.Ниже приведены фрагменты кода отправителя и получателя:

Код отправителя:

StackFlush(&snd_stack);
StackPush(&snd_stack, state_index);
StackPush(&snd_stack, current_ch);
StackPush(&snd_stack, actions_to_skip);
elements_in_stack = stack.top + 1;
for(int a=elements_in_stack-1;a>=0;a--)
                StackPush(&snd_stack, stack.contents[a]);
StackPush(&snd_stack, elements_in_stack);
elements_in_stack = parse_tree.top + 1;
for(int a=elements_in_stack-1;a>=0;a--)
                StackPush(&snd_stack, parse_tree.contents[a]);
StackPush(&snd_stack, elements_in_stack);
elements_in_stack = snd_stack.top+1;
MPI_Send(&elements_in_stack, 1, MPI_INT, (myrank + actions_to_skip) % mysize, MSG_ACTION_STACK_COUNT, MPI_COMM_WORLD);
MPI_Send(&snd_stack.contents[0], elements_in_stack, MPI_CHAR, (myrank + actions_to_skip) % mysize, MSG_ACTION_STACK, MPI_COMM_WORLD);

Код получателя:

MPI_Recv(&e_count, 1, MPI_INT, MPI_ANY_SOURCE, MSG_ACTION_STACK_COUNT, MPI_COMM_WORLD, &status);
if(e_count == 0){
                break;
}
while((bt_stack.top + e_count) >= bt_stack.maxSize - 1){usleep(500);}
pthread_mutex_lock(&mutex_bt_stack); //using mutex for accessing shared data among threads
MPI_Recv(&bt_stack.contents[bt_stack.top + 1], e_count, MPI_CHAR, status.MPI_SOURCE, MSG_ACTION_STACK, MPI_COMM_WORLD, &status);
bt_stack.top += e_count;
pthread_mutex_unlock(&mutex_bt_stack);

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

Неустранимая ошибка в MPI_Recv: Сообщение обрезано, стек ошибок:MPI_Recv (186).L Сообщение обрезано;Получено 21 байта, но размер буфера равен 19. Ранг 0 в задании 73 hpc081_56549 вызвал коллективный прерывание всех состояний выхода из ранга 0: убит сигналом 9.

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

1 Ответ

1 голос
/ 27 декабря 2011

Я не знаю, как выглядит остальная часть кода, но вот идея.Поскольку существует break, я предполагаю, что код получателя является частью цикла или оператора switch.В этом случае существует несоответствие между отправкой и получением, когда количество элементов становится равным 0:

  1. Отправитель отправит число элементов и сообщение нулевой длины (строка MPI_Send(&snd_stack.contents...).
  2. Не будет никакого соответствующего приема для этого второго сообщения, потому что получатель выходит из цикла.
  3. Тогда сообщение нулевой длины будет соответствовать чему-то другому, возможно, вызывая ошибку, которую вы видите внизлиния.
...