MPI - MPI_Recv中的消息截断

时间:2011-12-19 06:58:37

标签: c mpi parallel-processing

我在与MPI开发相关的项目中遇到问题。我正在使用MPI实现RNA解析算法,其中我开始基于一些解析规则解析输入字符串并使用主节点解析表(包含不同的状态和相关动作)。在解析表中,每个状态有多个动作可以并行完成。所以,我必须在不同的流程中分配这些行动。为此,我将当前状态和解析信息(解析的当前堆栈)发送到节点,使用单独的线程接收来自其他节点的操作,同时主线程忙于基于接收到的操作进行解析。以下是发件人和收件人的代码段:

发件人代码:

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)..........................................:MPI_Recv(buf = 0x5b8d7b1,count = 19,MPI_CHAR,src = 3,tag = 1,MPI_COMM_WORLD,status = 0x41732100)失败 MPIDI_CH3U_Request_unpack_uebuf(625)L消息被截断;收到21个字节但缓冲区大小为19 职位73 hpc081_56549中的等级0导致排名0的所有等级退出状态的集体中止:被信号9杀死。

我也尝试使用非阻塞MPI调用,但仍然存在类似的错误。

1 个答案:

答案 0 :(得分:1)

我不知道代码的其余部分是什么,但这是一个想法。由于存在break我假设接收器代码是循环或switch语句的一部分。如果是这种情况,则当元素计数变为0时,发送和接收之间存在不匹配:

  1. 发件人将发送元素计数和零长度消息(MPI_Send(&snd_stack.contents...行)。
  2. 第二条消息没有匹配的接收,因为接收器突然断开。
  3. 零长度消息将匹配其他内容,可能导致您看到的错误。