You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MPI_Type_create_subarray写入分布式数据出现无效数据的修复咨询

解决MPI分布式数据写入单个文件时出现NaN/垃圾数据的问题

看起来你的问题主要来自两个关键错误,让我们一步步拆解并修复:

1. 最严重的问题:MPI_Status变量声明错误

在Fortran中,MPI_Status类型并不是单个整数,而是一个大小为MPI_STATUS_SIZE的数组。你的代码里把istatus声明成了单个integer:

integer ierr,istatus,myrank,NPROCS,SUBARRAY,NUM,fh

当你调用MPI_File_write_all时,MPI会尝试写入这个变量的内存空间之外的区域,导致内存越界,破坏程序的状态(比如子数组类型的元数据),最终写入垃圾数据到文件中。

修复方法:
把istatus声明为符合要求的数组:

integer ierr, myrank, NPROCS, SUBARRAY, NUM, fh
integer istatus(MPI_STATUS_SIZE)

2. 次要问题:MPI_File_write_all的参数不匹配

你当前使用MPI_DOUBLE_PRECISION作为写入的数据类型,同时传入num(子数组元素个数)作为count。虽然理论上如果buf的内存布局和subarray类型完全一致时这种写法能工作,但更规范且不易出错的方式是直接使用你创建的SUBARRAY类型作为写入的数据类型,count设为1——因为SUBARRAY已经完整描述了你的子数组的大小和内存布局。

修复方法:
修改MPI_File_write_all的调用:

call mpi_file_write_all(fh, buf, 1, SUBARRAY, istatus, ierr)

这样MPI会自动将你的buf数组作为一个完整的子数组写入文件对应位置,无需手动计算元素个数。

3. 额外检查点

  • 确保运行程序时指定的进程数是5(mpiexec -n 5 ./your_program),因为你的代码只处理了rank 0到4的情况,多余的进程会因为未分配buf而崩溃。
  • 确认所有进程的buf维度和SUBSIZE严格匹配:比如rank 2的SUBSIZE是(2,1,2),buf分配为(0:1,1,0:1),这是正确的;其他进程的维度也都没问题。

修改后的完整代码

program test
use mpi
implicit none
integer ierr, myrank, NPROCS, SUBARRAY, NUM, fh
integer istatus(MPI_STATUS_SIZE)
INTEGER START(0:2), GSIZE(0:2), SUBSIZE(0:2), i,j,k
real*8, dimension(:,:,:), pointer:: buf
real*8 f(0:9)

call mpi_init(ierr)
call mpi_comm_size(MPI_COMM_WORLD, NPROCS, IERR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, MYRANK, IERR)

GSIZE(0)=2
GSIZE(1)=5
GSIZE(2)=5

IF(MYRANK.EQ.0)THEN
    allocate(buf(0:1,0:1,0:1))
    START(0)=0
    START(1)=0
    START(2)=0
    SUBSIZE(0)=2
    SUBSIZE(1)=2
    SUBSIZE(2)=2
    NUM=2*2*2
    buf=real(myrank)
ELSEIF(MYRANK.EQ.1)THEN
    allocate(buf(0:1,0:1,0:1))
    START(0)=0
    START(1)=2
    START(2)=0
    SUBSIZE(0)=2
    SUBSIZE(1)=2
    SUBSIZE(2)=2
    NUM=2*2*2
    buf=real(myrank)
ELSEIF(MYRANK.EQ.2)THEN
    allocate(buf(0:1,1,0:1))
    START(0)=0
    START(1)=4
    START(2)=0
    SUBSIZE(0)=2
    SUBSIZE(1)=1
    SUBSIZE(2)=2
    NUM=2*1*2
    buf=real(myrank)
ELSEIF(MYRANK.EQ.3)THEN
    allocate(buf(0:1,0:4,0:1))
    START(0)=0
    START(1)=0
    START(2)=2
    SUBSIZE(0)=2
    SUBSIZE(1)=5
    SUBSIZE(2)=2
    NUM=2*5*2
    buf=real(myrank)
ELSEIF(MYRANK.EQ.4)THEN
    allocate(buf(0:1,0:4,1))
    START(0)=0
    START(1)=0
    START(2)=4
    SUBSIZE(0)=2
    SUBSIZE(1)=5
    SUBSIZE(2)=1
    NUM=2*5*1
    buf=real(MYRANK)
ENDIF

CALL MPI_TYPE_CREATE_SUBARRAY(3, GSIZE, SUBSIZE, START, &
                              MPI_ORDER_fortran, MPI_DOUBLE_PRECISION, SUBARRAY, IERR)
CALL MPI_TYPE_COMMIT(SUBARRAY, IERR)

call mpi_file_open(mpi_comm_world, 'file', &
                   mpi_mode_wronly+mpi_mode_create, mpi_info_null, fh, ierr)
call mpi_file_set_view(fh, 0_mpi_offset_kind, &
                       mpi_double_precision, subarray, 'native', mpi_info_null, ierr)
call mpi_file_write_all(fh, buf, 1, SUBARRAY, istatus, ierr)
call mpi_file_close(fh, ierr)

CALL MPI_FINALIZE(IERR)
END

经过这些修改后,你的程序应该能正确将所有分布式数据写入单个文件,不会再出现NaN或垃圾数据。

内容的提问来源于stack exchange,提问作者chan lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:45:23