io - What is the best way to transfer data (Real and Integer arrays) between two runnings fortran programs on the same machine? -
we using file i/o need better/faster way. sample code appreciated.
by using files transfer, you're implementing form of message passing, , think natural fit sort of program. now, write uses shared memory when available , tcp/ip when not - or use library that, mpi, available, works, take advantage of shared memory if running on same machine, extend letting run them on different machines entirely without changing code.
so simple example of 1 program sending data second , waiting data back, we'd have 2 programs follows; 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) print *,'error: assumes n=2!' call mpi_abort(1,mpi_comm_world,ierr) endif !! 2 pes; other 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; sending second.' call mpi_send(inputdata, n*m, mpi_real, otherrank, firsttag, & mpi_comm_world, ierr) print *, rank, ': first: waiting return data...' call mpi_recv(processeddata, n*m, mpi_real, otherrank, backtag, & mpi_comm_world, rstatus, ierr) print *, rank, ': first: recieved data partner.' call mpi_finalize(ierr) end program first
and 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) print *,'error: assumes n=2!' call mpi_abort(1,mpi_comm_world,ierr) endif !! 2 pes; other 1 if we're 0, or 0 if we're 1. otherrank = comsize - (rank+1) print *, rank, ': second: waiting initial data...' call mpi_recv(inputdata, n*m, mpi_real, otherrank, firsttag, & mpi_comm_world, rstatus, ierr) print *, rank, ': second: adding 1 , 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
for clarity, stuff 2 programs must agree on ina module both use, here protocol.f90:
module protocol !! shared information 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
(a makefile building executables follows:)
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
and run 2 programs following:
$ mpiexec -n 1 ./first : -n 1 ./second 1 : second: waiting initial data... 0 : first: finished computing; sending second. 0 : first: waiting return data... 1 : second: adding 1 , sending back. 1 : second: completed 0 : first: recieved data partner. $
we give more relevant example if give more information workflow between 2 programs.
Comments
Post a Comment