Так что определение правильной стратегии ввода-вывода зависит от множества факторов. Если вы просто отправляете назад несколько собственных значений, и вы застряли в написании ASCII, вам может быть лучше просто отправить все данные обратно на обработку 0 для записи. Это не обычно выигрышная стратегия, поскольку она явно не масштабируется; но если объем данных очень мал, он может быть лучше, чем конфликт, связанный с попыткой записать в общий файл (что опять же сложнее с ASCII).
Ниже приведен код, который будет считывать объем данных обратно в proc 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
k Здесь есть что-то, что каждая задача имеет одно (или некоторое число)? И каждый имеет тот же ATOM_COUNT? – 2010-12-05 02:11:10
Ой, подождите - я не заметил неформатированной записи. Вы делаете это в ASCII? Если да, то (а) вы действительно не должны (он медленный, делает для больших файлов, и если вы действительно не распечатываете его и не анализируете на глаз, зачем беспокоиться?), И (б) вы, вероятно, из-за какого-либо параллельного подхода ввода-вывода. С тем, что вы делаете, поскольку выходные данные малы, вам, вероятно, лучше присвоить ранг 0 MPI_GATHER() все данные вместе и записать его, а не перебирать барьеры. – 2010-12-05 03:09:23