2010-12-05 2 views
1

Я пишу в файл следующим образом. Порядок не обязательно имеет значения (хотя это было бы неплохо, если бы я мог получить его по заказу K, как это было бы по существу в последовательном коде)Запись в файлы с MPI

  CALL MPI_BARRIER(MPI_COMM_WORLD, IERR) 
      OPEN(EIGENVALUES_UP_IO, FILE=EIGENVALUES_UP_PATH, ACCESS='APPEND') 
      WRITE(EIGENVALUES_UP_IO, *) K * 0.0001_DP * PI, (EIGENVALUES(J), J = 1, ATOM_COUNT) 
      CLOSE(EIGENVALUES_UP_IO) 

Я знаю, это, вероятно, будет самым худшим вариантом.

Я взглянул на MPI_FILE_WRITE_AT и т. Д., Но я не уверен, что они (напрямую) берут данные в форме, которую у меня есть?

Файл должен быть в том же формате, что и этот, который выводится как линия на К, с ATOM_COUNT + 1 столбцами. Значения REAL (8)

Я много раз охотился и не могу найти никаких простых ссылок на это. Любая помощь? :)

Аналогичный код в C (при условии, что это в основном так же, как FORTRAN) является столь же полезным

Спасибо!

+0

k Здесь есть что-то, что каждая задача имеет одно (или некоторое число)? И каждый имеет тот же ATOM_COUNT? – 2010-12-05 02:11:10

+0

Ой, подождите - я не заметил неформатированной записи. Вы делаете это в ASCII? Если да, то (а) вы действительно не должны (он медленный, делает для больших файлов, и если вы действительно не распечатываете его и не анализируете на глаз, зачем беспокоиться?), И (б) вы, вероятно, из-за какого-либо параллельного подхода ввода-вывода. С тем, что вы делаете, поскольку выходные данные малы, вам, вероятно, лучше присвоить ранг 0 MPI_GATHER() все данные вместе и записать его, а не перебирать барьеры. – 2010-12-05 03:09:23

ответ

2

Так что определение правильной стратегии ввода-вывода зависит от множества факторов. Если вы просто отправляете назад несколько собственных значений, и вы застряли в написании 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 
0

Если вы можете определить, сколько времени записи каждого ранга будет, вы можете вызвать MPI_SCAN(size, offset, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD) вычислить смещение, что каждый ранг должен начинаться, а затем все они могут вызова MPI_FILE_WRITE_AT. Это, вероятно, более подходит, если у вас много данных, и вы уверены, что ваша реализация MPI эффективно пишет (не сериализуется внутри или тому подобное).

Смежные вопросы