Запись в файлы с MPI - PullRequest
       33

Запись в файлы с MPI

1 голос
/ 05 декабря 2010

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

            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 и т. Д., Но я не уверен, что они (напрямую) принимают данные в той форме, которая у меня есть?

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

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

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

Спасибо!

Ответы [ 2 ]

2 голосов
/ 05 декабря 2010

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

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

...