使用MPI-IO的set_view与write_all的示例代码存在什么问题?
MPI-IO写入文件内容全0且体积异常问题修复
问题现象
构造23全1数组,6核运行MPI程序,预期每个进程写入1个元素,最终输出23全1的二进制文件,实际运行无报错,但输出文件全为0且体积远大于预期。
错误原因
- 坐标索引不匹配:
MPI_Cart_coords返回的笛卡尔坐标为0起始,而MPI_TYPE_CREATE_SUBARRAY指定了MPI_ORDER_FORTRAN(Fortran数组1起始),直接传入0起始的coords作为start参数会导致子数组位置越界,写入位置错误 - 拓扑参数未初始化:
periods数组未显式赋值,随机值可能导致笛卡尔拓扑创建异常 - 写入参数错误:
MPI_FILE_WRITE_all传入计数为6、类型为自定义子数组filetype,等于每个进程尝试写入6个全局子数组块,不仅写入位置完全错位,还会产生大量文件空洞撑大文件体积
修复方案
针对上述问题修改代码:
- 创建子数组时将
start赋值为coords+1,匹配Fortran数组索引规则 - 显式初始化
periods数组为.FALSE. - 修改写入调用,每个进程仅写入1个int元素即可
修正后完整代码
program test use mpi implicit none integer::rank,nproc,ierr,filetype,cart_comm integer::fh integer::buff(2,3) integer::gsize(2) integer::start(2) integer::subsize(2) integer::coords(2) integer:: nprocs_cart(2)=(/2,3/) logical::periods(2) = [.FALSE., .FALSE.] ! 显式初始化周期参数 call MPI_init(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, nproc, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) CALL MPI_Dims_create(nproc, 2, nprocs_cart, ierr) CALL MPI_Cart_create(MPI_COMM_WORLD, 2, nprocs_cart, periods, .TRUE., & cart_comm, ierr) CALL MPI_Comm_rank(cart_comm, rank, ierr) CALL MPI_Cart_coords(cart_comm, rank, 2, coords, ierr) start = coords + 1 ! 适配Fortran数组1起始规则 gsize=(/2,3/) subsize=(/1,1/) buff=1 call MPI_TYPE_CREATE_SUBARRAY(2,gsize,subsize,start,MPI_ORDER_FORTRAN,& MPI_int,filetype,ierr) call MPI_TYPE_COMMIT(filetype,ierr) call MPI_File_open(MPI_COMM_WORLD,'out.dat',& MPI_MODE_WRONLY + MPI_MODE_CREATE, MPI_INFO_NULL, fh,ierr) call MPI_File_set_view(fh,0,MPI_int,filetype,& "native",MPI_INFO_NULL,ierr) ! 每个进程仅写入1个int元素即可 CALL MPI_FILE_WRITE_all(fh, buff(1,1), 1, MPI_INT, MPI_STATUS_ignore, ierr) call MPI_File_close(fh,ierr) call MPI_FINALIZE(ierr) end program test
验证
修复后运行程序,输出的out.dat大小应为234=24字节(按int占4字节计算),读取后为全1的2*3数组,符合预期。
内容的提问来源于stack exchange,提问作者Mac cchiatooo
相关产品推荐
相关产品推荐

