Каков наилучший способ передачи данных (массивы вещественных и целых чисел) между двумя выполняющимися программами на одной машине? - PullRequest
0 голосов
/ 23 февраля 2011

В настоящее время мы используем файловый ввод / вывод, но нам нужен более быстрый и быстрый способ.Пример кода будет оценен.

Ответы [ 2 ]

1 голос
/ 25 февраля 2011

Используя файлы для передачи, вы уже внедрили форму передачи сообщений, и поэтому я думаю, что это было бы наиболее естественным для такой программы.Теперь вы можете написать что-нибудь самостоятельно, которое использует разделяемую память, когда доступно, и что-то вроде TCP / IP, когда нет - или вы можете просто использовать библиотеку, которая уже делает это, например, MPI, который широко доступен, работает, будет использовать преимущества совместно используемой памяти.если вы работаете на одной и той же машине, но затем также позволяете запускать их на разных машинах без изменения кода.

Так что в качестве простого примера одна программа отправляет данные в секунду, а затемв ожидании данных мы получили бы две программы следующим образом;first.f90

program first

    use protocol
    use mpi
    implicit none
    real, dimension(n,m) :: inputdata
    real, dimension(n,m) :: processeddata
    integer :: rank, comsize, ierr, otherrank
    integer :: rstatus(MPI_STATUS_SIZE)


    call MPI_INIT(ierr)
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
    call MPI_COMM_SIZE(MPI_COMM_WORLD, comsize, ierr)

    if (comsize /= 2) then 
        print *,'Error: this assumes n=2!'
        call MPI_ABORT(1,MPI_COMM_WORLD,ierr)
    endif

    !! 2 PEs; the other is 1 if we're 0, or 0 if we're 1.
    otherrank = comsize - (rank+1)

    inputdata = 1.
    inputdata = exp(sin(inputdata))

    print *, rank, ': first: finished computing; now sending to second.'
    call MPI_SEND(inputdata, n*m, MPI_REAL, otherrank, firsttag, &
                  MPI_COMM_WORLD, ierr)
    print *, rank, ': first: Now waiting for return data...'
    call MPI_RECV(processeddata, n*m, MPI_REAL, otherrank, backtag, &
                  MPI_COMM_WORLD, rstatus, ierr)
    print *, rank, ': first: recieved data from partner.'

    call MPI_FINALIZE(ierr)

end program first

и second.f90:

program second

    use protocol
    use mpi
    implicit none
    real, dimension(n,m) :: inputdata
    real, dimension(n,m) :: processeddata
    integer :: rank, comsize, ierr, otherrank
    integer :: rstatus(MPI_STATUS_SIZE)

    call MPI_INIT(ierr)
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
    call MPI_COMM_SIZE(MPI_COMM_WORLD, comsize, ierr)

    if (comsize /= 2) then 
        print *,'Error: this assumes n=2!'
        call MPI_ABORT(1,MPI_COMM_WORLD,ierr)
    endif

    !! 2 PEs; the other is 1 if we're 0, or 0 if we're 1.
    otherrank = comsize - (rank+1)

    print *, rank, ': second: Waiting for initial data...'
    call MPI_RECV(inputdata, n*m, MPI_REAL, otherrank, firsttag, &
                  MPI_COMM_WORLD, rstatus, ierr)

    print *, rank, ': second: adding 1 and sending back.'
    processeddata = inputdata + 1 
    call MPI_SEND(processeddata, n*m, MPI_REAL, otherrank, backtag, &
                  MPI_COMM_WORLD, ierr)

    print *, rank, ': second: completed'

    call MPI_FINALIZE(ierr)

end program second

Для ясности, то, что две программы должны согласовать, может быть в модуле, который они обе используют, здесь protocol.f90:

module protocol
    !! shared information like tag ids, etc goes here

    integer, parameter :: firsttag = 1
    integer, parameter :: backtag  = 2

    !! size of problem
    integer, parameter :: n = 10, m = 20 
end module protocol 

(Создается файл сборки для сборки исполняемых файлов:)

all: first second

FFLAGS=-g -Wall
F90=mpif90

%.mod: %.f90
        $(F90) -c $(FFLAGS) $^    

%.o: %.f90
        $(F90) -c $(FFLAGS) $^    

first: protocol.mod first.o
        $(F90) -o $@ first.o protocol.o

second: protocol.mod second.o
        $(F90) -o $@ second.o protocol.o

clean:
        rm -rf *.o *.mod

, а затем вы запускаете две программы следующим образом:

$ mpiexec -n 1 ./first : -n 1 ./second
           1 : second: Waiting for initial data...
           0 : first: finished computing; now sending to second.
           0 : first: Now waiting for return data...
           1 : second: adding 1 and sending back.
           1 : second: completed
           0 : first: recieved data from partner.
$

Конечно, мы могли бы дать вам более подходящий пример, если вы дадите нам больше информации о рабочих процессах между двумя программами.

0 голосов
/ 23 февраля 2011

Используете ли вы бинарный (неформатированный) файловый ввод / вывод? Если объем данных не огромен, это должно быть быстро.

В противном случае вы могли бы использовать межпроцессное взаимодействие, но это было бы более сложно. Вы можете найти код на C, который можно вызвать из Fortran с помощью привязки ISO C.

...