MPI Probe与Get_count获取消息长度异常为0问题求助
问题分析与解决
核心原因
你遇到的MPI_Get_count返回0的问题,本质是自定义MPI派生类型Point_type未被MPI正确识别。MPI_Get_count对于自定义类型,需要MPI能够解析该类型的内存布局和基本数据单元的映射关系,如果Point_type没有正确提交(调用MPI_Type_commit),或者定义过程有错误,MPI无法计算消息中包含的Point_type实例数量,就会返回0。
解决步骤
1. 确保Point_type正确定义并提交
自定义MPI类型必须完成完整的定义和提交流程,主进程和从进程都要执行这段代码:
// 假设Point结构体定义如下: typedef struct { double x; double y; int id; } Point; // 定义自定义类型的步骤 MPI_Datatype Point_type; int blocklengths[3] = {1, 1, 1}; MPI_Aint displacements[3]; MPI_Datatype types[3] = {MPI_DOUBLE, MPI_DOUBLE, MPI_INT}; // 计算每个成员的位移 displacements[0] = offsetof(Point, x); displacements[1] = offsetof(Point, y); displacements[2] = offsetof(Point, id); // 创建结构体类型 MPI_Type_create_struct(3, blocklengths, displacements, types, &Point_type); // 提交类型,让MPI识别 MPI_Type_commit(&Point_type);
注意:程序结束时记得调用MPI_Type_free(&Point_type)释放资源。
2. 替代方案:改用字节数计算
如果暂时无法解决自定义类型的问题,可以用MPI_BYTE作为MPI_Get_count的参数,手动计算Point实例的数量:
int byte_count; MPI_Get_count(&status2, MPI_BYTE, &byte_count); chunk_size = byte_count / sizeof(Point);
这种方法依赖于主从进程中Point结构体的内存布局完全一致(比如没有不同编译器的对齐差异),适合快速调试,但不如正确提交自定义类型可靠。
3. 调整通信逻辑(更稳妥)
可以修改主从进程的通信流程,先发送数据长度,再发送实际数据,避免依赖MPI_Probe获取自定义类型的数量:
- 主进程:发送完数据长度(这里是997)后,再发送
Point数据 - 从进程:先接收长度,再接收对应数量的
Point数据
示例代码修改:
// 主进程部分 MPI_Send(&recv_size, 1, MPI_INT, i, 0, MPI_COMM_WORLD); MPI_Send(points, recv_size, Point_type, i, 1, MPI_COMM_WORLD); // 从进程部分 MPI_Recv(&chunk_size, 1, MPI_INT, ROOT, 0, MPI_COMM_WORLD, &status2); if(chunk_size == 0) break; MPI_Recv(points, chunk_size, Point_type, ROOT, 1, MPI_COMM_WORLD, &status2);
这种方式不需要依赖MPI_Probe,逻辑更直观,也避免了自定义类型在MPI_Get_count中的兼容性问题。
内容的提问来源于stack exchange,提问作者Luca Lotifi
相关产品推荐
相关产品推荐

