FortranからのOmniRPCの使い方

ここでは、FortranからのOmniRPC APIの使い方について説明します 詳しいAPIについては、 Fortran API を参照して ください。

Fortranの簡単な例
リモート実行プログラムの作成
Fortranのクライアントプログラム
Fortranでの非同期呼び出しの例

Fortranの簡単な例

以下のfortranプログラムを考えてみましょう。内積を計算するプログ ラムです。main.fがメインプログラム、ip.fが内積を計算するサブルーチンで す。
main.f:
      double precision a(10),b(10),r
      do i = 1,10
         a(i) = i
         b(i) = i+10
      end do
      call innerprod(10,a,b,r)
      write(*,*) 'result=',r
      end

ip.f:
      subroutine innerprod(n,a,b,r)
      integer n
      double precision a(*),b(*),r
      interger i
      r = 0.0
      do i = 1,n
        r = r+a(i)*b(i)
      end do
      return
      end

このプログラムで、サブルーチンinnerprodをOmniRPCで呼び出してみることに します。

リモート実行プログラムの作成

Cと同じように、リモートホストにおいて、サブルーチンを実行するプログラ ムを作成します。そのために、innerprodに対するインタフェースを定義しま す。モジュール名はf_innerprod,関数名をinnerprodにします。
Module f_innerprod;

Define innerprod(IN int n, IN double a[n], IN double b[n],
        OUT double result[1])
Calls "Fortran" innerprod_(n,a,b,result);

サイズ指定に使われる引数は、スカラ変数にしなくてはなりません。 fortranのdouble precisionは、double型、real型は、float型になります。 CallsでFortranの関数を直接呼び出す場合には、"Fortran"と指定します。 ここで呼び出す関数名はfortranのmanglingされた関数名でなくてはなりませ ん。大抵のfortranコンパイラの場合には、manglingされた名前は関数名に"_" を付けたものです。関数名に"_"が入る場合には、g77(gcc)では"__"("_"が2 つ)が付くようにmanglingされることに注意してください。

この定義は以下の定義と同じです。スカラー引数に対しては、アドレス渡 しになります。

Module f_innerprod;

Define innerprod(IN int n, IN double a[n], IN double b[n],
        OUT double result[1])
{
    innerprod_(&n,a,b,result);
}

このIDLファイルから、OmniRPCリモート実行モジュールを生成します。IDLファ イルの名前をf_ip.idlとします。

% omrpc-fc f_ip.idl ip.f

このコマンドが実行されると、f_ip.rexというリモート実行プログラムが生成 されます。これをomrpc-registerで登録するのは、Cの場合と同じです。

% omrpc-register -register f_ip.rex

omrpc-fcでは、fortranのプログラムをf77というコマンドでコンパイルします。 もしも、異なるコンパイラを用いる場合には、-fcというオプションで変える ことができます。例えば、intelのifcを使う場合には以下のようにします。

% omrpc-fc -fc ifc f_ip.idl ip.f

Fortranのクライアントプログラム

さて、クライアントプログラムであるmain.fをOmniRPCを用いて、リモート実 行プログラムを呼び出すように変更します。

      double precision a(10),b(10),r
      call OMINRPC_INIT
      do i = 1,10
         a(i) = i
         b(i) = i+10
      end do
      call OMNIRPC_CALL("f_innerprod*",10,a,b,r)
      write(*,*) 'result=',r
      call OMNIRPC_FINALIZE
      end

OMNIRPC_INITで初期化をし、OMNIRPC_CALLで呼び出します。 OMNIRPC_CALLで指定するエントリ名は、インタフェースで定義した名前に"*" を最後に付けたものにすることに注意してください。モジュール名やホスト名 など、OmniRPCに渡す文字列の最後には"*"を付けてください。OmniRPCの Fortran APIでは"*"を文字列の最後とみなします。

このプログラムをコンパイルするには、omrpc-fcを使うことができます。

% omrpc-fc main.f

Fortranでの非同期呼び出しの例

最後に、 OmniRpcによる並列プログラム で示 した例をFortranで記述した例を示します。

      double precision res(10)
      double precision x
      integer ireqs(10)
      call omnirpc_init
      x = 0.0
      do i = 1, 10
         call omnirpc_call_async(ireqs(i),'calc_sin*',x,res(i))
         x = x + 1.0
      end do
      call omnirpc_wait_all(10,ireqs)
      do i = 1, 10
         write(*,*) 'res(',i, ')=',res(i)
      end do
      call omnirpc_finalize
      end
詳しいAPIについては、 Fortran API を参照して ください。