Неправилни резултати при четене на двоичен файл с MPI I/O

Аз съм нов в 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 (fwiw, не мога да компилирам тази програма, освен ако не поправя това)

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 master) - person Gilles Gouaillardet; 24.10.2017
comment
Благодаря ти. Промяната на MPI_STATUS на MPI_STATUS_IGNORE поправи изхода ми. - person rishu saxena; 24.10.2017