MPI_Scatter 较大阵列尺寸的分段故障

MPI_Scatter Segmentation fault with larger array size

提问人:Alec.Zhou 提问时间:2/3/2023 更新时间:3/12/2023 访问量:50

问:

我想简单地将一个一维大数组分散到所有进程,我观察到当数组大小大于大约 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);

我尝试并观察到:

  1. 我已经用 ulimit -s 检查了 linux 堆栈大小,并且 结果是无限的。
  2. 我已经检查了所有指针的内存 已成功 malloc。
  3. 我认为没有同步问题 因为MPI_Scatter是一个集体的呼吁。
  4. 我还观察到,当使用单个或两个进程时,较大的数组大小是可以的,数组可以成功地分发到每个进程;使用 4 个进程时,它始终是第三个进程报告 Segmentation fault: address not mmap to object at address (nil);使用 8 个进程时,第 3 和第 5 个进程将导致分段错误:地址未映射到地址0x1123f800处的对象

非常奇怪的问题让我困惑了几天,希望能从你们那里得到一些有用的建议,非常感谢。

分段故障 malloc MPI

评论


答:

1赞 Victor Eijkhout 2/3/2023 #1

我怀疑你正在达到 int 的 21.4 亿限制,即使你说你离这个限制只有 10 倍。您的数量是 ,但 MPI 例程仅采用发送的元素数量。测试你的数字是否适合整数,否则你就不走运了。fracPointDataEleTotallongint

....除非您安装支持 MPI-4 的最新 mpich,它具有例程和(对您而言)采用计数参数,并且要大得多。MPI_Send_cMPI_Scatter_cMPI_Count

(另外,为了确定,请测试您的 malloc 是否真的成功,并且您没有耗尽内存!

评论

1赞 Alec.Zhou 2/5/2023
谢谢你的回答。我已经确认所有数字都适合 int,似乎还有其他一些未知原因。
0赞 Victor Eijkhout 2/6/2023
四个进程仍然足够低,您可以使用穷人的并行调试器:。mpiexec -n 4 xterm -e gdb yourprogramm
1赞 Jeff Hammond 3/3/2023
或者完全避免需要的 xterm。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
0赞 jacob 3/12/2023 #2

您的 MPI 实现(应该在您的问题中明确提及,以便我们实际上可以查看)很有可能在内部将您的数据转换为字节,然后对字节进行操作。纯 C 整数最多可以索引 2,147,483,648 字节。这相当于 268,435,456 个 8 字节双元素。或者,在矩阵维度中,大约 2.33 × 1.15 亿,与开始遇到问题的阈值一致。

举一个明确的例子,Open MPI 在内部将数据类型序列化为 的字节数,然后递归调用相同的数据,但相应地具有更大(但仍然)的参数。这导致了溢出。您的 MPI 很可能遇到了类似的问题。MPI_SendrecvMPI_SendrecvintcountMPI_Scatter