使用 MPI I/O 读取二进制文件时结果不正确
Incorrect results when reading binary file with MPI I/O
我是 MPI 的新手,正在为读取二进制文件而苦苦挣扎。
具体来说,我有一个存储在二进制文件中的 $198\times 50 \times 50$ 整数数组(具体来说是 16 位整数)。我想使用 2 个计算节点来处理这个文件。所以有两个 MPI 进程,每个进程将处理一半的输入。我正在使用函数 MPI_FILE_READ_AT 来读取各个区域。我希望数组值填充我传递给函数调用的 variable/argument 'bucket'。但是 'bucket' 条目的完整性检查打印告诉我存储桶中的值都不正确。我觉得我的论点是错误的。
program main
use mpi
implicit none
integer :: i, error, num_processes, id, fh
integer(MPI_OFFSET_KIND) :: filesize, offset
integer(MPI_OFFSET_KIND) :: num_bytes_per_process
integer(MPI_OFFSET_KIND) :: num_bytes_this_process
integer :: num_ints_per_process, num_ints_this_process
integer(kind = 2), dimension(:), allocatable :: bucket
character(len=100) :: inputFileName
integer, parameter :: INTKIND=2
! Initialize
inputFileName = 'xyz_50x50'
print *, 'MPI_OFFSET_KIND =', MPI_OFFSET_KIND
! MPI basics
call MPI_Init ( error )
call MPI_Comm_size ( MPI_COMM_WORLD, num_processes, error )
call MPI_Comm_rank ( MPI_COMM_WORLD, id, error )
! Open the file
call MPI_FILE_OPEN(MPI_COMM_WORLD, inputFileName, MPI_MODE_RDONLY, &
MPI_INFO_NULL, fh, error)
! get the size of the file
call MPI_File_get_size(fh, filesize, error)
! Note: filesize is the TOTAL number of bytes in the file
num_bytes_per_process = filesize/num_processes
num_ints_per_process = num_bytes_per_process/INTKIND
offset = id * num_bytes_per_process
num_bytes_this_process = min(num_bytes_per_process, filesize - offset)
num_ints_this_process = num_bytes_this_process/INTKIND
allocate(bucket(num_ints_this_process))
call MPI_FILE_READ_AT(fh, offset, bucket, num_ints_this_process, &
MPI_SHORT, MPI_STATUS_SIZE, error)
do i = 1, num_ints_this_process
if (bucket(i) /= 0) then
print *, "my id is ", id, " and bucket(",i,")=", bucket(i)
endif
enddo
! close the file
call MPI_File_close(fh, error)
! close mpi
call MPI_Finalize(error)
end program main
你必须使用 MPI_STATUS_IGNORE
而不是 MPI_STATUS_SIZE
(首先,我无法编译这个程序,除非我修复它)
call MPI_FILE_READ_AT(fh, offset, bucket, num_ints_this_process, &
MPI_SHORT, MPI_STATUS_IGNORE, error)
请注意,由于所有 MPI 任务都在 同一时间 读取文件,因此您宁愿使用集体 MPI_File_read_at_all()
子例程以提高性能。
我是 MPI 的新手,正在为读取二进制文件而苦苦挣扎。 具体来说,我有一个存储在二进制文件中的 $198\times 50 \times 50$ 整数数组(具体来说是 16 位整数)。我想使用 2 个计算节点来处理这个文件。所以有两个 MPI 进程,每个进程将处理一半的输入。我正在使用函数 MPI_FILE_READ_AT 来读取各个区域。我希望数组值填充我传递给函数调用的 variable/argument 'bucket'。但是 'bucket' 条目的完整性检查打印告诉我存储桶中的值都不正确。我觉得我的论点是错误的。
program main
use mpi
implicit none
integer :: i, error, num_processes, id, fh
integer(MPI_OFFSET_KIND) :: filesize, offset
integer(MPI_OFFSET_KIND) :: num_bytes_per_process
integer(MPI_OFFSET_KIND) :: num_bytes_this_process
integer :: num_ints_per_process, num_ints_this_process
integer(kind = 2), dimension(:), allocatable :: bucket
character(len=100) :: inputFileName
integer, parameter :: INTKIND=2
! Initialize
inputFileName = 'xyz_50x50'
print *, 'MPI_OFFSET_KIND =', MPI_OFFSET_KIND
! MPI basics
call MPI_Init ( error )
call MPI_Comm_size ( MPI_COMM_WORLD, num_processes, error )
call MPI_Comm_rank ( MPI_COMM_WORLD, id, error )
! Open the file
call MPI_FILE_OPEN(MPI_COMM_WORLD, inputFileName, MPI_MODE_RDONLY, &
MPI_INFO_NULL, fh, error)
! get the size of the file
call MPI_File_get_size(fh, filesize, error)
! Note: filesize is the TOTAL number of bytes in the file
num_bytes_per_process = filesize/num_processes
num_ints_per_process = num_bytes_per_process/INTKIND
offset = id * num_bytes_per_process
num_bytes_this_process = min(num_bytes_per_process, filesize - offset)
num_ints_this_process = num_bytes_this_process/INTKIND
allocate(bucket(num_ints_this_process))
call MPI_FILE_READ_AT(fh, offset, bucket, num_ints_this_process, &
MPI_SHORT, MPI_STATUS_SIZE, error)
do i = 1, num_ints_this_process
if (bucket(i) /= 0) then
print *, "my id is ", id, " and bucket(",i,")=", bucket(i)
endif
enddo
! close the file
call MPI_File_close(fh, error)
! close mpi
call MPI_Finalize(error)
end program main
你必须使用 MPI_STATUS_IGNORE
而不是 MPI_STATUS_SIZE
(首先,我无法编译这个程序,除非我修复它)
call MPI_FILE_READ_AT(fh, offset, bucket, num_ints_this_process, &
MPI_SHORT, MPI_STATUS_IGNORE, error)
请注意,由于所有 MPI 任务都在 同一时间 读取文件,因此您宁愿使用集体 MPI_File_read_at_all()
子例程以提高性能。