[BACK]Return to ox_math.tex CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_math / documents

Diff for /OpenXM/src/ox_math/documents/ox_math.tex between version 1.2 and 1.9

version 1.2, 1999/11/02 06:12:00 version 1.9, 2005/07/20 16:24:56
Line 1 
Line 1 
 %#!platex  %#!platex
 %% $OpenXM$  %% $OpenXM: OpenXM/src/ox_math/documents/ox_math.tex,v 1.8 2005/07/19 15:58:37 ohara Exp $
   
 \documentclass{jarticle}  \documentclass{jarticle}
 \title{Mathematica の Open XM 化について  \title{Mathematica の Open XM 化について
 % \\ {\small --- Open Mathematica サーバの内部構成 ---}  % \\ {\small --- Open Mathematica サーバの内部構成 ---}
 }  }
 %\date{January 19, 1999}  \date{
 \date{July 12, 1999}  %January 19, 1999
   %July 12, 1999
   November 25, 1999
   (Revised July 20, 2005)
   }
 \author{小原功任}  \author{小原功任}
   
   \def\oxmath{{\tt ox\_math}}
   
 \begin{document}  \begin{document}
 \maketitle  \maketitle
   
 \section{Open Mathematicaの構成}  \section{我々が提供するもの}
   
 Open Mathmatica サーバはOpen XM クライアントおよびmathematica カーネルと  我々が提供するのは二つのプログラムとそのソースである。一つ目は
 通信する。Open Mathmatica サーバは起動直後にmathematica カーネルを起動し、  \oxmath プログラムであり、これは OpenXM サーバの一種である。二つ目は
 mathematica カーネルと協調して動作する。mathematica カーネルとは  {\tt math2ox} であり、OpenXM クライアントである。
 MathLink ライブラリを利用して通信する。Open Mathmatica サーバはMathLink  
   動作環境は Solaris, Linux および Windows、対象としている Mathematica の
   バージョンは、3.0 〜 4.2 までである。バージョン 5.x については、我々が所
   有していないため調査していない。
   
   Windows 上では \oxmath は、cygwin のもとで動作する。\oxmath の Windows
   対応は藤本さんによる(2002年4月)。ありがとう。
   
   \section{Open Mathematica サーバの構成}
   
   Open Mathmatica サーバ(\oxmath)はOpen XM クライアントおよび Mathematica
   Kernel と通信する。\oxmath は起動直後に Mathematica Kernel を起動し、
   Mathematica Kernel と協調して動作する。Mathematica Kernel とは MathLink
   ライブラリを利用して通信する。つまり \oxmath は MathLink
 のラッパだと思ってよい。Open XM クライアントとの間はソケットを利用して通  のラッパだと思ってよい。Open XM クライアントとの間はソケットを利用して通
 信する。Open Mathmatica サーバはファイルディスクリプタ 3,4 が既にオープ  信する。\oxmath はファイルディスクリプタ 3,4 が既にオープ
 ンされていると思って, 3 から読み込み、4 に書き出す。  ンされていると思って, 3 から読み込み、4 に書き出す。
   
 さらに、Open Mathmatica サーバはコントロールプロセスからシグナルを受け取  さらに \oxmath には計算中断機能が必要であるが、この機能は 2003年のはじめに実装された。
 る場合がある。シグナルを受け取った場合には,相応の動作が必要であるが、現  
 在は実装していない.  SIGUSR1 (SM\_control\_reset\_connection) は計算が全  
 て終わってからOX\_SYNC\_BALL を投げるので、実際には意味がない。  
   
 \section{OX スタックマシン}  次に、Open XM 規約より \oxmath はスタックマシンでなければならない。
 スタックのオブジェクトは cmo 型の変数、あるいはその派生クラスである.  スタックのオブジェクトは cmo 型の変数、あるいはその派生クラスである.
 つまり、Open XM 規約で定められたデータ形式を流用している.  つまり、Open XM 規約で定められたデータ形式を流用している.
 % cmo 構造体およびその派生クラスは/home/ohara/openxxx/lib/oxlib.h で定義さ  
 % れている.  
 この方法の利点は Open XM プロトコルを通して通信するにあたって  この方法の利点は Open XM プロトコルを通して通信するにあたって
 特にデータの変換を必要としないことである.  すなわちCMO の各データタイプ  特にデータの変換を必要としないことである.  すなわちCMO の各データタイプ
 は Open Mathematicaサーバ(スタックマシン)の内部でも, CMO として保持する  は \oxmath の内部でも, CMO として保持する
 わけである.  わけである.
   
 サーバの各関数は cmo* を受け取り、タグをみて実際のクラスが何であるかを  サーバの各関数は cmo* を受け取り、タグをみて実際のクラスが何であるかを
 知り、動作を決定する.  知り、動作を決定する.
   
 \section{Mathematica との通信(MathLink) について}  現在、実装されているスタックマシン命令は
   SM\_popCMO, SM\_popString, SM\_pops, SM\_executeFunction,
   SM\_executeStringByLocalParser, SM\_mathcap, SM\_setMathcap(受け取るだけ
   で何もしない)である。
   
 CMO は 次のように変換されてから, MathLink を通して送られる.  \section{MathLink プログラミングと \oxmath}
   
   最初に、MathLink プログラミングについての基礎的事項を説明し、
   次に \oxmath の Mathematica Kernel との通信部分について述べる。
   
   MathLink プログラミングについては、概ね、Mathematica
   Book~\cite{Wolfram-1996} や宮地~\cite{miyachi-1998} などを参照すればよい
   が、必ずしもこれらの書籍に明確に書かれているわけではない(探せば見つかる
   が)。
   
   まず MathLink とは、Wolfram が提供するライブラリであり、Mathematica のネッ
   トワーク対応部分に相当する。Mathematica Kernel と通信するプログラムを書
   こうとするならば、MathLink を利用する必要がある。MathLink の内部構成は明
   らかにされていないが、{\bf 大部分はネットワーク透過的}である(例外はある)。
   
   まず、MathLink の通信路で交換されるデータが何なのか、ということを理解す
   る必要がある。答は{\bf Mathematicaの式}である。これは自明ではない。
   次のような式がその例である。
   \begin{verbatim}
       EvaluatePacket[Sin[\$VersionNumber]]
       ReturnPacket[Sin[x]]
       InputNamePacket["In[1]:= "]
       MenuPacket[1,"Interrupt> "]
   \end{verbatim}
   このような *Packet[] を \cite{Wolfram-1996}ではパケットと呼んでいる.
   MathLink を用いて、確実なプログラミングをするためには、これらのパケット
   を正しく扱う必要がある。
   
   さて、Mathematica Kernel の起動および通信路の確立については省略する。
   いったん、通信路が確立されたら、
 \begin{enumerate}  \begin{enumerate}
 \item CMO\_INT32 は MLTKINT (多倍長整数型).  \item Mathematica Kernel に式を送る。
 \item CMO\_STRING は MLTKSTR (文字列型).  \item Mathematica Kernel から式を受け取る。
 \item その他のタイプの CMO は ToExpression[文字列] として送る.  
 \end{enumerate}  \end{enumerate}
   を繰り返すのが MathLink でのプログラミングである。
   
 上で述べられている ToExpression は Mathematica の組み込み関数であり,  \oxmath は Mathematica と以下のような意味で{\bf 文字列ベース}で通信して
 文字列を引数として Mathematica の式を返す.  いる。まず Mathematica Kernel に評価させたい式が、C 言語の文字列で与えら
   れているとして、link で指し示すMathematica Kernel に
   \begin{verbatim}
   int ml_evaluateStringByLocalParser(char *string)
   {
       MLPutFunction(link, "EvaluatePacket", 1);
       MLPutFunction(link, "ToExpression", 1);
       MLPutString(link, string);
       MLEndPacket(link);
   }
   \end{verbatim}
   として送信する。パケットは、
   EvaluatePacket[ToExpression[{\it string}]] である。
   ここで ToExpression は Mathematica の組み込み関数であり,
   文字列 {\it string} を引数として Mathematica の式を返す.
 (\cite[pp.407]{Wolfram-1996})  (\cite[pp.407]{Wolfram-1996})
   
 ここで一つ注意をしておく.  評価された結果を配列 str に格納するには、単純には次のようになる。
 MathLink では, int 型以外のデータを MLTKINT として送ることは残念ながらで  
 きない.  したがって CMO\_ZZ を直接, 整数型であると Mathematica に思わせ  
 ることはできないのである.  そこで, 次のような方法をとることになる.  
   
 \begin{verbatim}  \begin{verbatim}
 char *CONVERT_ZZ_TO_CSTRING(cmo_t zz);  int receive_sample(char str[])
   
 int main()  
 {  {
   char *s;      while (MLNextPacket(link) != RETURNPKT)
   cmo_t zz;  /* zz.tag == CMO_ZZ */          MLNewPacket(link);
   MLINK lp;  /* MathLink Socket */      switch(MLGetNext(link)) {
   ...      MLTKSTR:
   s = CONVERT_ZZ_TO_CSTRING(zz);          MLGetString(link, &str);
   MLPutFunction(lp, "ToExpression", 1);          ...
   MLPutString(lp, s);      MLTKINT:
   ...          ...
       }
       MLNewPacket(link);
 }  }
 \end{verbatim}  \end{verbatim}
   この例では ReturnPacket[] 以外を無視しているが、実際にはこんなに単純には
   書けない。\oxmath の実装では、mlo.c の
   ml\_next\_packet(), ml\_new\_packet(), ml\_read\_packet(),
   ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_read\_textpacket()
   などを見てほしい。
   
 このようにすると, Mathematica 側では, 例えば  \bigskip
   
   文字列によらず、CMO を送ることもできる.
   
   \oxmath は, CMO を次の規則で MathLink のオブジェクトに変換する.
 \[  \[
 \mbox{\tt ToExpression["1234567890"]}  \begin{array}{lcl}
   \mbox {CMO\_INT32} & \to & \mbox{MLTKINT}, \\
   \mbox {CMO\_STRING} & \to & \mbox{MLTKSTR}, \\
   \mbox {CMO\_LIST} & \to & \mbox{MLTKFUNC}, \\
   \mbox {その他の CMO} & \to & \mbox{ToExpression[文字列]}
   \end{array}
 \]  \]
 という評価が行われ, 文字列データから整数が復元される.  逆に MathLink のオブジェクトは次の規則で CMO に変換される.
   \[
   \begin{array}{lcl}
   \mbox {MLTKERR} & \to & \mbox{CMO\_ERROR2}, \\
   \mbox {MLTKINT} & \to & \mbox{CMO\_ZZ}, \\
   \mbox {MLTKSTR} & \to & \mbox{CMO\_STRING},\\
   \mbox {MLTKREAL} & \to & \mbox{CMO\_IEEE\_DOUBLE\_FLOAT}, \\
   \mbox {MLTKSYM} & \to & \mbox{CMO\_STRING}, \\
   \mbox {MLTKFUNC} & \to & \mbox{CMO\_LIST}
   \end{array}
   \]
   この変換規則は明らかに可逆でないので注意.
   
 逆に, Mathematica から送られた整数データは,  \bigskip
 マシン整数の範囲内であれば, int として  
 取得可能(MLGetInteger を使う)であるが,  
 受け取る前に int に収まるか否かを知ることはできない.  
 また, 直接 CMO\_ZZ として取得することも不可能である.  
 (MathLink 上でどのような形式でデータ交換されているのかの  
 情報は手元にある資料からは得られなかった)  
   
   CMO\_ZZ をもとに実装を説明しよう.
   まず, MLTKINT は多倍長整数型であるが, MathLink の内部データ構造が
   公開されていないため,
   CMO\_ZZ (あるいは GNU GMP library の整数)を直接 MLTKINT に
   変換することはできない.  つまり CMO\_ZZ が整数型であると MathLink に知ら
   せることはできない.  そこで, 次のような方法をとることになる.
   
   \begin{verbatim}
   export MLINK link;
   int ml_send_cmo_zz(cmo *m)
   {
       MLPutFunction(link, "ToExpression", 1);
       MLPutString(link, new_string_set_cmo(m));
   }
   \end{verbatim}
   
   このようにすると, Mathematica 側では, 例えば ToExpression["1234567890"]
   の評価が行われ, 文字列データから整数 1234567890 が復元される.
   
   逆に, Mathematica から送られた多倍長整数は, マシン整数の範囲内であれば,
   int として取得可能(MLGetInteger を使う)であるが, 受け取る前に int に収ま
   るか否かを知ることはできない. int に収まらない場合、データが切り捨てられ
   てしまうので注意が必要である.  また, 直接 CMO\_ZZ として取得することも不
   可能である.  (MathLink 上でどのような形式でデータ交換されているのかの情
   報は手元にある資料からは得られなかった)
   
 しかしながら, たとえ Mathematica 側から整数データが送られていたとしても,  しかしながら, たとえ Mathematica 側から整数データが送られていたとしても,
 そのデータを文字列に変換して受け取ることは MathLink の機構上可能である.  そのデータを文字列に変換して受け取ることは MathLink の機構上可能である.
   
 これを利用して, 我々は次のようにして整数を受け取る.  これを利用して, 我々は次のようにして整数を受け取る.
 \begin{verbatim}  \begin{verbatim}
 cmo_t CONVERT_CSTRING_TO_ZZ(char *s);  export MLINK link;
   cmo_zz* ml_receive_cmo_zz()
 int main()  
 {  {
   MLINK lp;      cmo_zz *zz = NULL;
   char *s;      if(MLGetNext(link) == MLTKINT) {
   cmo_t zz;          char *s;
   ...          MLGetString(link, &s);
   if(MLGetNext(lp) == MLTHINT) {          zz = new_cmo_zz_set_string(s);
     MLGetString(lp, &s);          MLDisownString(link, s);
     zz = CONVERT_CSTRING_TO_ZZ(s);  /* zz.tag == CMO_ZZ */      }
   }      return zz;
   ...  }
 }  
 \end{verbatim}  \end{verbatim}
   
 つまり、Mathematica から整数データを文字列として受け取り、  つまり、Mathematica から整数を文字列として受け取り、その文字列を
 その文字列を OX サーバ側で CMO\_ZZ に直している。  \oxmath が CMO\_ZZ に直している。
   
 基本的に MathLink では全てのデータを文字列で受け取るしか方法はない。どの  % このように基本的に MathLink では全てのデータを文字列で受け取るしか方法は
 ような種類のデータであるかは受け取る前に知ることはできる。データの型は、  % ない。どのような種類のデータであるかは受け取る前に知ることはできる。デー
 MLTKERR(エラー), MLTKINT(整数), MLTKSTR(文字列), MLREAL(実数), MLTKSYM  % タの型は、MLTKERR(エラー), MLTKINT(整数), MLTKSTR(文字列), MLTKREAL(実数),
 (シンボル), MLTKFUNC(関数) のいずれかである。このような事情で  % MLTKSYM (シンボル), MLTKFUNC(関数) のいずれかである。このような事情で
 Mathematica から受け取ったデータは基本的に CMO\_STRINGとしてスタックに積  % Mathematica から受け取ったデータは基本的に CMO\_STRINGとしてスタックに積
 まれるので、クライアント側でその文字列の解釈をする必要がでてくる。  % まれるので、クライアント側でその文字列の解釈をする必要がでてくる。しかし
   % ながら、全ての MathLink オブジェクトが文字列に変換できるわけではないので、
   % その取り扱いには注意を要する。
   
 しかしながら、全ての MathLink オブジェクトが文字列に変換できるわけではな  \section{\oxmath への計算中断機能の実装}
 いので、その取り扱いには注意を要する。  
 まだ、実装していないが、多項式(CMO\_???\_PORINOMIAL)の扱いが難しい。  
   
 \section{個々のスタックマシン命令の実装}  \noindent
 現在、実装しているのは  {\bf 注意: {\tt ox\_math\_interruption.tex}
 SM\_popCMO, SM\_popString, SM\_pops, SM\_executeFunction,  に Risa/Asir Conference (2003) での講演原稿がある.}
 SM\_executeStringByLocalParser, SM\_mathcap, SM\_setMathcap(受け取るだけ  
 で何もしない)である。  
   
   OpenXM プロトコルは、エンジンに対して、計算中断機能を要求する。\oxmath
   のような wrapper プログラムでは、そのような機能を実装するのは一般には難
   しいが、MathLink には Mathematica Book~\cite{Wolfram-1996} に書かれてい
   ない機能があり(\cite{MathSource-Google1}, \cite{MathSource-Google2},
   \cite{Math-Output1})、そのひとつを用いて、\oxmath に計算中断機能を実装し
   た。この節では、その実装について説明する。
   
   Mathematica Kernel に対する割り込みは、
   \begin{enumerate}
   \item MLPutMessage で Mathematica Kernel に MLInterruptMessage を送る。
   \item 通信路の後始末を行い、最終的に ReturnPacket[\$Aborted] を受け取る。
   \end{enumerate}
   ことでなされる。
   MLPutMessage は MathLink の非公開関数でネットワーク透過性はない。
   Unix と Windows では異なるが、Unix の場合、MLInterruptMessage の実体は
   SIGINT である。
   通信路の後始末には、{\bf Mathematica Kernel のバージョン依存性がある}ので、
   それを回避すると、結局、次の手順になる。
   \begin{enumerate}
   \item MLPutMessage(link, MLInterruptMessage)
   \item MenuPacket[1,"Interrupt> "] を受け取れば計算が中断されている
   \item MLPutString(link, "$\backslash$n")
   \item MenuPacket[0,"Interrupt> "] を受け取る
   \item MLPutString(link, "a")
   \item TextPacket["..."] を受け取る
   \item EvaluatePacket[0] を送って、ReturnPacket[...] をふたつ受け取る。
   最初のものが ReturnPacket[\$Aborted] である。
   \end{enumerate}
   
   最後の手順を説明する。
   ここで、ReturnPacket[\$Aborted] が素直に返ってくればいいのであるが、
   バージョン 3.x では返ってくるのに、バージョン4.xでは、何故か、
   返ってこず、次の計算を行うとき、ふたつまとめて返ってくる。
   よって、ダミーにEvaluatePacket[0] を送るのである。
   
 \section{Mathematica を OX のクライアントに}  \section{Mathematica を OX のクライアントに}
   
   OpenXM クライアントは Mathematica の外部プログラム({\tt math2ox}) の形で
   実現されている。すなわち、Mathematica と math2ox の間は MathLink プロト
   コルで、math2ox と OpenXM サーバの間は OpenXM プロトコルで通信し、
   math2ox が適切に情報を変換しながらやりとりする。その意味で wrapper の一
   種であるとも言える。
   
   利用するには、最初に
 \begin{verbatim}  \begin{verbatim}
 In[1]:= Install["math2ox"]  In[1]:= Install["math2ox"]
 \end{verbatim}  \end{verbatim}
 とすると、外部プログラムをロードし、  として、math2ox をロードしなければならない。
   Mathematica に新たに定義されるコマンドは、\\
   {\tt OxStart[s\_String], OxStartInsecure[s\_String, p\_Integer, q\_Integer],
   \\
   OxStartRemoteSSH[s\_String, host\_String],
   \\
   OxExecuteString[id\_Integer, s\_String],
   OxParse[id\_Integer, s\_String],
   \\
   OxSendMessage[id\_Integer, s\_String],
   OxGet[id\_Integer],
   \\
   OxPopCMO[id\_Integer],
   OxPopString[id\_Integer],
   \\
   OxClose[id\_Integer],
   OxReset[id\_Integer]}
   \\
   の11個である。
   
   math2ox をロードしたら、
 \begin{verbatim}  \begin{verbatim}
 In[2] := OxStart["ox_sm1"]  In[2] := pid = OxStart["ox_sm1"]
 \end{verbatim}  \end{verbatim}
 によって OpenXM サーバに接続する。接続先は ox\_sm1 である。  によって OpenXM サーバに接続する。この場合の接続先は ox\_sm1 である。
   返り値 pid は、セッション番号である。
   もちろん
   \begin{verbatim}
   In[2] := pid = OxStartInsecure["water.s.kanazawa-u.ac.jp", 1300, 1400]
   \end{verbatim}
   のようにして、insecure モードで接続してもよい。ただしこの場合は、
   あらかじめ {\tt Run[]} 等で、OpenXM サーバを起動しておかなければならない。
   
 接続が成功したら適当にデータを送ってみよう。  接続が成功したらデータを送ってみよう。
 利用できるコマンドは  
 {\tt OxStart[s\_String], OxExecute[s\_String], OxPopString[], OxClose[], OxReset[]}  
 の五つである。計算が終わったら、  
 \begin{verbatim}  \begin{verbatim}
 In[3] := OxClose[]  In[3] := OxParse[pid, "(CMO_LIST, (CMO_STRING, "hello world"), (CMO_ZERO))"]
 \end{verbatim}  \end{verbatim}
   のように CMO expression を指定することによって、
   任意の CMO を送信できる。
   正しくない CMO の場合には、何も送信されない。
   また、CMO ではなく、
   \begin{verbatim}
   In[4] := OxParse[pid, "(OX_COMMAND, (SM_popCMO))"]
   \end{verbatim}
   などとして、OX メッセージの形で記述することもできる。
   注意しなければならないのは、SM コマンドの場合、OX スタックマシンから
   OX メッセージが送られてくる場合があるが、OxParse[] を用いた場合、
   このメッセージは自動的には受信しない(現在の仕様では)。したがって明示的に
   受信する必要がある。そのためには
   \begin{verbatim}
   In[5] := OxGet[pid]
   \end{verbatim}
   とするだけでよい。返ってくるオブジェクトは CMO に対応するものである。
   \begin{verbatim}
   In[6] := OxPopCMO[pid]
   \end{verbatim}
   を用いる場合にはもちろん {\tt OxGet[pid]} を呼び出す必要はない。
   
   計算を実行するには {\tt OxExecute[pid, ...]}
   (SM\_executeStringByLocalParser) か、適切な OX メッセージを送信すること。
   
   計算が終わったら、
   \begin{verbatim}
   In[7] := OxClose[pid]
   \end{verbatim}
 とすると、接続が終了する。  とすると、接続が終了する。
   
 \appendix  \appendix
Line 177  typedef unsigned long int mp_limb_t;  
Line 366  typedef unsigned long int mp_limb_t;  
 \begin{thebibliography}{99}  \begin{thebibliography}{99}
 \bibitem{Openxxx-1998}  \bibitem{Openxxx-1998}
 野呂正行, 高山信毅.  野呂正行, 高山信毅.
 {Open xxx の設計と実装, xxx = asir,kan}, 1998/10/11  {Open XM の設計と実装 --- Open message eXchange protocol for Mathematics},
   November 22, 1999, Revised March 4, 2005.
 \bibitem{Ohara-Takayama-Noro-1999}  \bibitem{Ohara-Takayama-Noro-1999}
 小原功任, 高山信毅, 野呂正行.  小原功任, 高山信毅, 野呂正行.
 {Open asir 入門}.  {Open asir 入門}, 1999, 数式処理, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG 出版, Tokyo).
 \bibitem{Wolfram-1992}  \bibitem{Wolfram-1992}
 ウルフラム.  ウルフラム.
 {Mathematica (日本語版)},  {Mathematica (日本語版)},
Line 189  typedef unsigned long int mp_limb_t;  
Line 379  typedef unsigned long int mp_limb_t;  
 Stephen Wolfram.  Stephen Wolfram.
 {The Mathematica Book}, Third edition,  {The Mathematica Book}, Third edition,
 Wolfram Media/Cambridge University Press, 1996.  Wolfram Media/Cambridge University Press, 1996.
   
 \bibitem{miyachi-1998}  \bibitem{miyachi-1998}
 宮地力.  宮地力.
 {Mathematica によるネットワークプログラミング},  {Mathematica によるネットワークプログラミング},
 岩波コンピュータサイエンス,  岩波コンピュータサイエンス,
 岩波書店, 1998.  岩波書店, 1998.
   \bibitem{MathSource-Google1}
   Todd Gayley.
   [mg17015] in MathArchive,
   1999 April.
   \bibitem{MathSource-Google2}
   昔の MathLink にあった MLSignal の解説.
   (以前、Google のキャッシュにあったが、もうない)
   \bibitem{Math-Output1}
   mathlink.h, libMLa のシンボル表, mprep の生成するソース.
 \end{thebibliography}  \end{thebibliography}
   
 \end{document}  \end{document}

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.9

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>