Таким образом, определение правильной стратегии ввода-вывода зависит от множества факторов.Если вы просто отправляете обратно несколько собственных значений и застряли при записи ASCII, вам лучше всего просто отправить все данные обратно в процесс 0 для записи.Это не , как правило, выигрышная стратегия, так как она явно не масштабируется;но если объем данных очень мал, это может быть лучше, чем конфликт, связанный с попыткой записи в общий файл (что опять же сложнее с ASCII).
Ниже приведен код, в котором объем данных возвращается к процедуре 0, при условии, что у всех одинаковый объем данных.
Другой подход заключается в том, чтобы каждый записывал свои собственные ksи собственные значения, а затем в качестве шага постобработки, как только программа будет завершена, объедините их все вместе.Это позволяет избежать шага MPI и (с правильной файловой системой) может масштабироваться довольно просто, и это легко;лучше ли это, достаточно легко проверить, и будет зависеть от объема данных, количества процессоров и базовой файловой системы.
program testio
use mpi
implicit none
integer, parameter :: atom_count = 5
integer, parameter :: kpertask = 2
integer, parameter :: fileunit = 7
integer, parameter :: io_master = 0
double precision, parameter :: pi = 3.14159
integer :: totalk
integer :: ierr
integer :: rank, nprocs
integer :: handle
integer(kind=MPI_OFFSET_KIND) :: offset
integer :: filetype
integer :: j,k
double precision, dimension(atom_count, kpertask) :: eigenvalues
double precision, dimension(kpertask) :: ks
double precision, allocatable, dimension(:,:):: alleigenvals
double precision, allocatable, dimension(:) :: allks
call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
totalk = nprocs*kpertask
!! setup test data
do k=1,kpertask
ks(k) = (rank*kpertask+k)*1.d-4*PI
do j=1,atom_count
eigenvalues(j,k) = rank*100+j
enddo
enddo
!! Everyone sends proc 0 their data
if (rank == 0) then
allocate(allks(totalk))
allocate(alleigenvals(atom_count, totalk))
endif
call MPI_GATHER(ks, kpertask, MPI_DOUBLE_PRECISION, &
allks, kpertask, MPI_DOUBLE_PRECISION, &
io_master, MPI_COMM_WORLD, ierr)
call MPI_GATHER(eigenvalues, kpertask*atom_count, MPI_DOUBLE_PRECISION, &
alleigenvals, kpertask*atom_count, MPI_DOUBLE_PRECISION, &
io_master, MPI_COMM_WORLD, ierr)
if (rank == 0) then
open(unit=fileunit, file='output.txt')
do k=1,totalk
WRITE(fileunit, *) allks(k), (alleigenvals(j,k), j = 1, atom_count)
enddo
close(unit=fileunit)
deallocate(allks)
deallocate(alleigenvals)
endif
call MPI_FINALIZE(ierr)
end program testio