Неверные результаты при чтении бинарного файла с помощью ввода/вывода MPI

Я новичок в MPI и борюсь с чтением двоичного файла. В частности, у меня есть массив $198\times 50\times 50$ целых чисел (точнее, 16-битных целых чисел), хранящийся в двоичном файле. Я хочу использовать 2 вычислительных узла для обработки этого файла. Таким образом, есть два процесса MPI, и каждый процесс будет обрабатывать половину ввода. Я использую функцию MPI_FILE_READ_AT для чтения соответствующих регионов. Я ожидаю, что значения массива заполнят «ведро» переменной/аргумента, которое я передам вызову функции. Но проверка работоспособности, распечатанная из записей «ведра», говорит мне, что все значения в ведре неверны. Я чувствую, что ошибаюсь в аргументах.

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

person rishu saxena    schedule 24.10.2017    source источник
comment
Пожалуйста, используйте fortran для всех вопросов по Fortran. Конкретная версия здесь не очень важна. Версия библиотеки MPI и версия компилятора важнее.   -  person Vladimir F    schedule 24.10.2017
comment
Я использую mvapich2/2.2, который поставляется с gcc 5.2.   -  person rishu saxena    schedule 24.10.2017


Ответы (1)


вы должны использовать 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().

person Gilles Gouaillardet    schedule 24.10.2017
comment
Честно говоря, большинство реализаций MPI компилируют это. Но некоторые ловят. - person Vladimir F; 24.10.2017
comment
справедливо, я думаю, что это больше связано с поведением компилятора. gfortran 7.1.0 не компилируется, но gfortran 4.8.5 — счастливая панда (оба протестированы с последним мастером Open MPI) - person Gilles Gouaillardet; 24.10.2017
comment
Спасибо. Изменение MPI_STATUS на MPI_STATUS_IGNORE исправило мой вывод. - person rishu saxena; 24.10.2017