提问人:Alec.Zhou 提问时间:2/3/2023 更新时间:3/12/2023 访问量:50
MPI_Scatter 较大阵列尺寸的分段故障
MPI_Scatter Segmentation fault with larger array size
问:
我想简单地将一个一维大数组分散到所有进程,我观察到当数组大小大于大约 2.5*1.15 亿时(一维数组实际上是一个有 250 万行和 115 列的矩阵,每个数字都是双精度),一些进程会报告分割错误。1*1.15亿或2*1.15亿是可以的!!!
错误消息是这样的:
Caught signal 11 (Segmentation fault: address not mapped to object at address (nil))
Caught signal 11 (Segmentation fault: address not mapped to object at address 0x1123f800)
代码片段为:
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
double *pointData = NULL;
double *fracPointData = NULL;
long pointDataEleTotal = numRows * numColumn;
long fracPointDataEleTotal = pointDataEleTotal / size;
if(rank == 0){
pointData = (double *)malloc(sizeof(double) * pointDataEleTotal);
initialize pointData
fracPointData = (double *)malloc(sizeof(double) * fracPointDataEleTotal);
}
if(rank != 0){
fracPointData = (double *)malloc(sizeof(double) * fracPointDataEleTotal);
}
MPI_Scatter(pointData, fracPointDataEleTotal, MPI_DOUBLE, fracPointData, fracPointDataEleTotal, MPI_DOUBLE, 0, MPI_COMM_WORLD);
我尝试并观察到:
- 我已经用
ulimit -s
检查了 linux 堆栈大小,并且 结果是无限
的。 - 我已经检查了所有指针的内存 已成功 malloc。
- 我认为没有同步问题 因为MPI_Scatter是一个集体的呼吁。
- 我还观察到,当使用单个或两个进程时,较大的数组大小是可以的,数组可以成功地分发到每个进程;使用 4 个进程时,它始终是第三个进程报告
Segmentation fault: address not mmap to object at address (nil);
使用 8 个进程时,第 3 和第 5 个进程将导致分段错误:地址未映射到地址0x1123f800处的对象
非常奇怪的问题让我困惑了几天,希望能从你们那里得到一些有用的建议,非常感谢。
答:
我怀疑你正在达到 int 的 21.4 亿限制,即使你说你离这个限制只有 10 倍。您的数量是 ,但 MPI 例程仅采用发送的元素数量。测试你的数字是否适合整数,否则你就不走运了。fracPointDataEleTotal
long
int
....除非您安装支持 MPI-4 的最新 mpich,它具有例程和(对您而言)采用计数参数,并且要大得多。MPI_Send_c
MPI_Scatter_c
MPI_Count
(另外,为了确定,请测试您的 malloc 是否真的成功,并且您没有耗尽内存!
评论
mpiexec -n 4 xterm -e gdb yourprogramm
mpirun -n 8 gdb -ex "set width 1000" -ex "thread apply all bt" -ex run -ex bt -ex "set confirm off" -ex quit --args program input
您的 MPI 实现(应该在您的问题中明确提及,以便我们实际上可以查看)很有可能在内部将您的数据转换为字节,然后对字节进行操作。纯 C 整数最多可以索引 2,147,483,648 字节。这相当于 268,435,456 个 8 字节双元素。或者,在矩阵维度中,大约 2.33 × 1.15 亿,与开始遇到问题的阈值一致。
举一个明确的例子,Open MPI 在内部将数据类型序列化为 的字节数,然后递归调用相同的数据,但相应地具有更大(但仍然)的参数。这导致了溢出。您的 MPI 很可能遇到了类似的问题。MPI_Sendrecv
MPI_Sendrecv
int
count
MPI_Scatter
评论