【问题标题】:MPI - Message Truncation in MPI_RecvMPI - MPI_Recv 中的消息截断
【发布时间】:2012-01-23 09:23:21
【问题描述】:

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

发件人代码:

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 调用,但仍然出现类似错误。

【问题讨论】:

  • 该错误表明MPI_Recv 正在接收比预期更多的数据(21 个字符而不是 19 个)。您是否有多个线程运行接收器代码?如果是这样,很可能您有一个线程接收用于另一个线程的数据,因此不同的e_count

标签: c mpi parallel-processing


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2019-04-25
    • 2014-09-02
    • 2011-01-21
    • 2019-08-23
    • 1970-01-01
    • 2023-03-23
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多