问题描述
问题
我使用 FFTW 来计算 MPI 并行化就地 3D FFT,特别是使用 fftw_mpi_plan_dft_r2c_3d()
,它通常有效。最近,我对将大数据量与少量 cpu 内核/MPI 进程混合起来很感兴趣。使用 2 个进程,全局大小 gridsize*gridsize*gridsize
的 3D FFT 失败并出现错误
[s81n11:31843] *** MPI_Sendrecv 发生错误
[s81n11:31843] *** 进程报告 [1582235649,0]
[s81n11:31843] *** 在通信器上 MPI COMMUNICATOR 6 DUP FROM 5
[s81n11:31843] *** MPI_ERR_COUNT:无效的计数参数
[s81n11:31843] *** MPI_ERRORS_ARE_FATAL(此通信器中的进程现在将中止,
[s81n11:31843] *** 可能还有你的 MPI 工作)
如果我使用 gridsize >= 2048
。请注意,使用例如它可以正常工作1 或 3 个进程。
我怀疑这归结为 MPI_Sendrecv()
中的 MPI 消息大小有限。对于 2 个进程,每个局部网格的物理大小为 size = (gridsize/2)*gridsize*(2*(gridsize/2 + 1))
,其中全局网格分布在第一个维度上,最后一个维度接收少量的 padding。对于 gridsize = 2048
,size = 1.001*2³²
。我对 gridsize = 2047
没有问题,对于 size = 0.999*2³²
。
-
问题究竟出在哪里?最好指出确切的
unsigned int
(或其他)罪魁祸首。 -
如果我直接负责 MPI 调用,我可以使用多个调用分块执行通信。但是,由于 FFTW 在内部调用 MPI,我该如何解决这个问题?如果不是太复杂,我想我什至愿意破解 FFTW/MPI 源。
虽然其他人之前一定遇到过这个问题,但我在网上找不到任何关于 FFTW 限制的信息。感谢有关该主题的任何参考。
我在 64 位 Linux 上使用 FFTW 3.3.9 和 MPICH 3.3.2 和 OpenMPI 4.0.3 时发现了问题。
示例代码
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <fftw3-mpi.h>
int main(int argc,char* argv[]) {
/* Set grid size */
ptrdiff_t gridsize = 32;
if (argc > 1)
gridsize = atoi(argv[1]);
ptrdiff_t gridsize_padding = 2*(gridsize/2 + 1);
/* Initialize MPI */
MPI_Init(NULL,NULL);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
fftw_mpi_init();
/* Allocate grid */
ptrdiff_t gridsize_local;
ptrdiff_t gridsize_local_i,gridstart_local_i;
ptrdiff_t gridsize_local_j,gridstart_local_j;
double* grid = fftw_alloc_real(fftw_mpi_local_size_3d_transposed(
gridsize,gridsize,gridsize_padding,MPI_COMM_WORLD,&gridsize_local_i,&gridstart_local_i,&gridsize_local_j,&gridstart_local_j
));
assert(gridsize_local_i == gridsize_local_j);
gridsize_local = gridsize_local_i;
if (rank == 0)
printf("gridsize %td\n",gridsize);
printf("rank %d got gridsize_local = %td\n",rank,gridsize_local);
/* Nullify grid */
ptrdiff_t i,j,k;
for (i = 0; i < gridsize_local; i++) {
for (j = 0; j < gridsize; j++) {
for (k = 0; k < gridsize_padding; k++) {
grid[(i*gridsize + j)*gridsize_padding + k] = 0.0;
}
}
}
/* Carry out FFT */
fftw_plan plan = fftw_mpi_plan_dft_r2c_3d(
gridsize,grid,(fftw_complex*) grid,FFTW_ESTIMATE | FFTW_MPI_TRANSPOSED_OUT
);
fftw_mpi_gather_wisdom(MPI_COMM_WORLD);
fftw_mpi_broadcast_wisdom(MPI_COMM_WORLD);
fftw_execute(plan);
/* Clean up */
fftw_free(grid);
fftw_destroy_plan(plan);
fftw_mpi_cleanup();
MPI_Finalize();
return 0;
}
假设您已经安装了 MPI 和 FFTW 并且环境配置适当,您可以使用
编译上面的fft.c
mpicc -I/path/to/fftw/include -I/path/to/mpi/include -c -o fft.o fft.c
mpicc fft.o -o fft -L/path/to/fftw/lib -Wl,-rpath=/path/to/fftw/lib -lfftw3_mpi -lfftw3 -L/path/to/mpi/lib -Wl,-rpath=/path/to/mpi/lib -lmpi
使用 2 个进程执行 3D FFT,例如gridsize
为 64,现在做
mpiexec -n 2 ./fft 64
不会发生任何事情,因为不会检查或打印任何结果。以 2048 的 gridsize
运行会在大约一分钟后产生崩溃。 警告:以 2048 的 gridsize
运行将占用 64 GB 内存 (!),因此您可能无法对此进行测试。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)