現在、ファイルI / Oを使用していますが、より良い/より高速な方法が必要です。サンプルコードをいただければ幸いです。
2 に答える
転送にファイルを使用することで、メッセージ パッシングの形式を既に実装しているので、この種のプログラムにはそれが最も自然に適合すると思います。ここで、利用可能な場合は共有メモリを使用し、利用できない場合は TCP/IP のようなものを自分で作成することもできます。または、広く利用可能で動作する MPI のように共有メモリを利用するライブラリを使用することもできます。同じマシンで実行している場合、コードを変更せずに別のマシンでそれらを完全に実行できるようにも拡張されます。
したがって、あるプログラムが別のプログラムにデータを送信し、データの返信を待機する簡単な例として、次のような 2 つのプログラムがあります。最初.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
明確にするために、2 つのプログラムが同意しなければならないものは、両方が使用するモジュール (ここでは 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
次に、次のように 2 つのプログラムを実行します。
$ 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.
$
2 つのプログラム間のワークフローについてさらに情報を提供していただければ、より適切な例を提供できます。
バイナリ (フォーマットされていない) ファイル I/O を使用していますか? データ量が膨大でない限り、高速である必要があります。
それ以外の場合は、プロセス間通信を使用できますが、より複雑になります。ISO C Binding を使用して Fortran から呼び出すことができる C のコードを見つけることができます。