まず、始めに簡単な例から始めましょう。例として、次のような1から10まで のsin関数の値を計算するプログラムを考えることにします。
#include <stdio.h> #include <math.h> int main(){ int i; double x, res[10]; x = 0.0; for(i = 0; i < 10; i++){ res[i] = sin(x); x += 1.0; } for(i = 0; i < 10; i++) printf("sin(%d)=%g\n",i,res[i]); }
このプログラムのsinの計算の部分をOmniRpcでリモートホストで計算してみる ことにします。 ここの説明では、遠隔呼び出しを行う側の計算機を クライアントホスト、遠隔呼び出しによって手続が実行される側の計算機を リモートホストと呼ぶことにします。
さて、この最初の説明では簡単のために以下のような環境を仮定します。
なお、ファイルシステムはshareされている必要はありません。
OmniRpcでは、ホストファイルに記述されたリモートホストでリモート実行プ ログラムを起動するために、プログラムの実行の最初に初期化APIである OmniRpcInitでomrpc_agentというプログラムを起動します。このAgentは、プ ログラム実行毎に起動され、プログラム実行中は実行されています。この Agentは、rshもしくはGlobus GRAM、sshで、必要な認証を行うための起動方法 で実行されます。この他にも、agentはリモートノードに登録されているモジュー ル情報へのアクセス、リモートノードのスケジューラへのインタフェース、通 信の多重化などの機能を提供します。この機能の指定方法については、 12. ホストファイルの記述 を参照してください。
上の図で、agentはOmniRPC agentを示し、rexはリモート実行プログラムです。 この例では、agentとrexは同じdennis上で実行されます。
Module calc_sin; Globals { #include <math.h> } Define calc_sin(double IN x, double OUT result[]){ *result = sin(x); }
まず、ModuleはこのIDLファイルで定義されるモジュール名を定義します。こ の例では、exampleにしました。
インタフェースはDefine文で定義します。 この例ではsinにしました。引数は、データタイプとその引数がinput(読み込 まれる)であるか、output(書き込みがある)であるかを定義します。 OmniRpcでは、元のsin関数のように関数の値を関数の返り値で返すことができ ないので、例のようにOUTの引数で返します。{...}で囲まれた部分では、リモー トホストで実際に実行する内容について、C言語で記述します。sin関数を呼び 出し、その値をOUTの引数であるresultに書き込みます。
Globalsに指定されている部分には、このモジュールで定義される関 数で必要とされる任意のCプログラムを記述しておくことができます。この例 では、sin関数の呼び出しに必要なファイルをincludeしています。このIDLファイルから、OmniRPCのリモート実行モジュール生成プログラム omrpc-ccによって、リモート実行プログラムを生成します。 では、次のコマンドで変換しましょう。
% omrpc-cc calc_sin.idl -lm
このプログラムが実行されると、calc_sin.rexというファイルが生成されます。 これが、りモート実行プログラムとなります。
なお、一つのリモート実行モジュールには複数の関数を定義することができま す。なお、詳しい定義については 13. IDLファイルの記述 を参照してください。
リモート実行プログラムを作成したら、次にそのリモート実行プログラムを登 録します。登録は、omrpc-registerで行います。
% omrpc-register -register calc_sin.rex
このプログラムは、ホームディレクトリに.omrpc-registryというディレクト リを作り、このの下にモジュール名と関数名、リモート実行プログラムのパス のデータベースを作ります。
これで、リモートホスト側の準備はできました。クライアントホスト側の準備 にうつりましょう。
#include <OmniRpc.h> #include <stdio.h> #include <math.h> int main(int argc,char *argv[]){ int i; double x, res[10]; OmniRpcInit(&argc,&argv); x = 0.0; for(i = 0; i < 10; i++){ OmniRpcCall("calc_sin",x,&res[i]); x += 1.0; } for(i = 0; i < 10; i++) printf("sin(%d)=%g\n",i,res[i]); OmniRpcFinalize(); }
まず、OmniRpcのライブラリを用いる前に、OmniRpcInitを呼び出さなくてはな りません。また、プログラムの終了時にはOmniRpcFinialize()をよびます。 OmniRpc.hには、これらの関数のプロトタイプが宣言されていますので、 includeしてください。
これを、コンパイルします。
% omrpc-cc -o test.exe test.c
omrpc-ccを使わずに、直接コンパイルしてもかまいません。
% cc -I/usr/local/omrpc/include -o test.exe test.c -L/usr/local/omrpc/lib -lomrpc_client -lomrpc_io
デフォールトでは、/usr/local/omrpcにインストールされていますが、もしも、 これ以外のディレクトリにインストールした場合には/usr/local/omrpcをイン ストールしたディレクトリに変えてください。
OmniRpcでは、通常、どのリモートホストを用いて実行するのかを ホストファイルにxmlを使って記述します。この例で仮定している 環境設定の場合は、以下のように記述します。
<?xml version="1.0" ?> <OmniRpcConfig> <Host name="prost" /> </OmniRpcConfig>
これを、hosts.xmlとします。
この例では、最も単純な設定なので、これだけでOKです。詳しくは、???を参 照してください。
これで、準備ができました。あとは、プログラムを実行するだけです。
% test.exe --hostfile hosts.xml
host.xmlに指定されているリモートホストからsinという名前のリモート関数 を探し、起動します。なお、--hostfileでホストファイルが指定されなかった 場合には、ホームディレクトリの~/.omrpc-registryにあるhosts.xmlがつかわ れます。
OmniRpcを使うための手順をまとめておきます。