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

Annotation of OpenXM/src/ox_math/documents/ox_math.tex, Revision 1.9

1.1       ohara       1: %#!platex
1.9     ! ohara       2: %% $OpenXM: OpenXM/src/ox_math/documents/ox_math.tex,v 1.8 2005/07/19 15:58:37 ohara Exp $
1.1       ohara       3:
                      4: \documentclass{jarticle}
                      5: \title{Mathematica の Open XM 化について
                      6: % \\ {\small --- Open Mathematica サーバの内部構成 ---}
                      7: }
1.9     ! ohara       8: \date{
        !             9: %January 19, 1999
        !            10: %July 12, 1999
        !            11: November 25, 1999
1.8       ohara      12: (Revised July 20, 2005)
                     13: }
1.1       ohara      14: \author{小原功任}
                     15:
1.8       ohara      16: \def\oxmath{{\tt ox\_math}}
                     17:
1.1       ohara      18: \begin{document}
                     19: \maketitle
1.7       takayama   20:
1.6       ohara      21: \section{我々が提供するもの}
                     22:
                     23: 我々が提供するのは二つのプログラムとそのソースである。一つ目は
1.9     ! ohara      24: \oxmath プログラムであり、これは OpenXM サーバの一種である。二つ目は
        !            25: {\tt math2ox} であり、OpenXM クライアントである。
1.6       ohara      26:
1.8       ohara      27: 動作環境は Solaris, Linux および Windows、対象としている Mathematica の
                     28: バージョンは、3.0 〜 4.2 までである。バージョン 5.x については、我々が所
                     29: 有していないため調査していない。
                     30:
                     31: Windows 上では \oxmath は、cygwin のもとで動作する。\oxmath の Windows
                     32: 対応は藤本さんによる(2002年4月)。ありがとう。
1.6       ohara      33:
                     34: \section{Open Mathematica サーバの構成}
1.1       ohara      35:
1.8       ohara      36: Open Mathmatica サーバ(\oxmath)はOpen XM クライアントおよび Mathematica
                     37: Kernel と通信する。\oxmath は起動直後に Mathematica Kernel を起動し、
                     38: Mathematica Kernel と協調して動作する。Mathematica Kernel とは MathLink
                     39: ライブラリを利用して通信する。つまり \oxmath は MathLink
1.1       ohara      40: のラッパだと思ってよい。Open XM クライアントとの間はソケットを利用して通
1.8       ohara      41: 信する。\oxmath はファイルディスクリプタ 3,4 が既にオープ
1.1       ohara      42: ンされていると思って, 3 から読み込み、4 に書き出す。
                     43:
1.8       ohara      44: さらに \oxmath には計算中断機能が必要であるが、この機能は 2003年のはじめに実装された。
1.1       ohara      45:
1.9     ! ohara      46: 次に、Open XM 規約より \oxmath はスタックマシンでなければならない。
1.1       ohara      47: スタックのオブジェクトは cmo 型の変数、あるいはその派生クラスである.
                     48: つまり、Open XM 規約で定められたデータ形式を流用している.
1.2       ohara      49: この方法の利点は Open XM プロトコルを通して通信するにあたって
1.1       ohara      50: 特にデータの変換を必要としないことである.  すなわちCMO の各データタイプ
1.9     ! ohara      51: は \oxmath の内部でも, CMO として保持する
1.1       ohara      52: わけである.
                     53:
                     54: サーバの各関数は cmo* を受け取り、タグをみて実際のクラスが何であるかを
                     55: 知り、動作を決定する.
                     56:
1.9     ! ohara      57: 現在、実装されているスタックマシン命令は
        !            58: SM\_popCMO, SM\_popString, SM\_pops, SM\_executeFunction,
        !            59: SM\_executeStringByLocalParser, SM\_mathcap, SM\_setMathcap(受け取るだけ
        !            60: で何もしない)である。
        !            61:
        !            62: \section{MathLink プログラミングと \oxmath}
        !            63:
        !            64: 最初に、MathLink プログラミングについての基礎的事項を説明し、
        !            65: 次に \oxmath の Mathematica Kernel との通信部分について述べる。
1.8       ohara      66:
1.9     ! ohara      67: MathLink プログラミングについては、概ね、Mathematica
1.8       ohara      68: Book~\cite{Wolfram-1996} や宮地~\cite{miyachi-1998} などを参照すればよい
                     69: が、必ずしもこれらの書籍に明確に書かれているわけではない(探せば見つかる
                     70: が)。
                     71:
                     72: まず MathLink とは、Wolfram が提供するライブラリであり、Mathematica のネッ
                     73: トワーク対応部分に相当する。Mathematica Kernel と通信するプログラムを書
                     74: こうとするならば、MathLink を利用する必要がある。MathLink の内部構成は明
                     75: らかにされていないが、{\bf 大部分はネットワーク透過的}である(例外はある)。
                     76:
                     77: まず、MathLink の通信路で交換されるデータが何なのか、ということを理解す
                     78: る必要がある。答は{\bf Mathematicaの式}である。これは自明ではない。
                     79: 次のような式がその例である。
                     80: \begin{verbatim}
                     81:     EvaluatePacket[Sin[\$VersionNumber]]
                     82:     ReturnPacket[Sin[x]]
                     83:     InputNamePacket["In[1]:= "]
                     84:     MenuPacket[1,"Interrupt> "]
                     85: \end{verbatim}
                     86: このような *Packet[] を \cite{Wolfram-1996}ではパケットと呼んでいる.
                     87: MathLink を用いて、確実なプログラミングをするためには、これらのパケット
                     88: を正しく扱う必要がある。
                     89:
                     90: さて、Mathematica Kernel の起動および通信路の確立については省略する。
                     91: いったん、通信路が確立されたら、
                     92: \begin{enumerate}
                     93: \item Mathematica Kernel に式を送る。
                     94: \item Mathematica Kernel から式を受け取る。
                     95: \end{enumerate}
                     96: を繰り返すのが MathLink でのプログラミングである。
                     97:
                     98: \oxmath は Mathematica と以下のような意味で{\bf 文字列ベース}で通信して
                     99: いる。まず Mathematica Kernel に評価させたい式が、C 言語の文字列で与えら
                    100: れているとして、link で指し示すMathematica Kernel に
                    101: \begin{verbatim}
1.9     ! ohara     102: int ml_evaluateStringByLocalParser(char *string)
1.8       ohara     103: {
                    104:     MLPutFunction(link, "EvaluatePacket", 1);
                    105:     MLPutFunction(link, "ToExpression", 1);
1.9     ! ohara     106:     MLPutString(link, string);
1.8       ohara     107:     MLEndPacket(link);
                    108: }
                    109: \end{verbatim}
                    110: として送信する。パケットは、
1.9     ! ohara     111: EvaluatePacket[ToExpression[{\it string}]] である。
        !           112: ここで ToExpression は Mathematica の組み込み関数であり,
        !           113: 文字列 {\it string} を引数として Mathematica の式を返す.
        !           114: (\cite[pp.407]{Wolfram-1996})
1.8       ohara     115:
                    116: 評価された結果を配列 str に格納するには、単純には次のようになる。
                    117: \begin{verbatim}
                    118: int receive_sample(char str[])
                    119: {
                    120:     while (MLNextPacket(link) != RETURNPKT)
                    121:         MLNewPacket(link);
                    122:     switch(MLGetNext(link)) {
                    123:     MLTKSTR:
                    124:         MLGetString(link, &str);
                    125:         ...
                    126:     MLTKINT:
                    127:         ...
                    128:     }
                    129:     MLNewPacket(link);
                    130: }
                    131: \end{verbatim}
                    132: この例では ReturnPacket[] 以外を無視しているが、実際にはこんなに単純には
                    133: 書けない。\oxmath の実装では、mlo.c の
                    134: ml\_next\_packet(), ml\_new\_packet(), ml\_read\_packet(),
                    135: ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_read\_textpacket()
                    136: などを見てほしい。
                    137:
1.9     ! ohara     138: \bigskip
1.1       ohara     139:
1.9     ! ohara     140: 文字列によらず、CMO を送ることもできる.
1.1       ohara     141:
1.9     ! ohara     142: \oxmath は, CMO を次の規則で MathLink のオブジェクトに変換する.
        !           143: \[
        !           144: \begin{array}{lcl}
        !           145: \mbox {CMO\_INT32} & \to & \mbox{MLTKINT}, \\
        !           146: \mbox {CMO\_STRING} & \to & \mbox{MLTKSTR}, \\
        !           147: \mbox {CMO\_LIST} & \to & \mbox{MLTKFUNC}, \\
        !           148: \mbox {その他の CMO} & \to & \mbox{ToExpression[文字列]}
        !           149: \end{array}
        !           150: \]
        !           151: 逆に MathLink のオブジェクトは次の規則で CMO に変換される.
        !           152: \[
        !           153: \begin{array}{lcl}
        !           154: \mbox {MLTKERR} & \to & \mbox{CMO\_ERROR2}, \\
        !           155: \mbox {MLTKINT} & \to & \mbox{CMO\_ZZ}, \\
        !           156: \mbox {MLTKSTR} & \to & \mbox{CMO\_STRING},\\
        !           157: \mbox {MLTKREAL} & \to & \mbox{CMO\_IEEE\_DOUBLE\_FLOAT}, \\
        !           158: \mbox {MLTKSYM} & \to & \mbox{CMO\_STRING}, \\
        !           159: \mbox {MLTKFUNC} & \to & \mbox{CMO\_LIST}
        !           160: \end{array}
        !           161: \]
        !           162: この変換規則は明らかに可逆でないので注意.
1.1       ohara     163:
1.9     ! ohara     164: \bigskip
1.1       ohara     165:
1.9     ! ohara     166: CMO\_ZZ をもとに実装を説明しよう.
        !           167: まず, MLTKINT は多倍長整数型であるが, MathLink の内部データ構造が
        !           168: 公開されていないため,
        !           169: CMO\_ZZ (あるいは GNU GMP library の整数)を直接 MLTKINT に
        !           170: 変換することはできない.  つまり CMO\_ZZ が整数型であると MathLink に知ら
        !           171: せることはできない.  そこで, 次のような方法をとることになる.
1.1       ohara     172:
                    173: \begin{verbatim}
1.9     ! ohara     174: export MLINK link;
        !           175: int ml_send_cmo_zz(cmo *m)
1.1       ohara     176: {
1.9     ! ohara     177:     MLPutFunction(link, "ToExpression", 1);
        !           178:     MLPutString(link, new_string_set_cmo(m));
1.1       ohara     179: }
                    180: \end{verbatim}
                    181:
1.9     ! ohara     182: このようにすると, Mathematica 側では, 例えば ToExpression["1234567890"]
        !           183: の評価が行われ, 文字列データから整数 1234567890 が復元される.
1.1       ohara     184:
1.9     ! ohara     185: 逆に, Mathematica から送られた多倍長整数は, マシン整数の範囲内であれば,
1.4       ohara     186: int として取得可能(MLGetInteger を使う)であるが, 受け取る前に int に収ま
                    187: るか否かを知ることはできない. int に収まらない場合、データが切り捨てられ
                    188: てしまうので注意が必要である.  また, 直接 CMO\_ZZ として取得することも不
                    189: 可能である.  (MathLink 上でどのような形式でデータ交換されているのかの情
                    190: 報は手元にある資料からは得られなかった)
1.1       ohara     191:
                    192: しかしながら, たとえ Mathematica 側から整数データが送られていたとしても,
                    193: そのデータを文字列に変換して受け取ることは MathLink の機構上可能である.
                    194:
                    195: これを利用して, 我々は次のようにして整数を受け取る.
                    196: \begin{verbatim}
1.9     ! ohara     197: export MLINK link;
        !           198: cmo_zz* ml_receive_cmo_zz()
1.1       ohara     199: {
1.9     ! ohara     200:     cmo_zz *zz = NULL;
        !           201:     if(MLGetNext(link) == MLTKINT) {
        !           202:         char *s;
        !           203:         MLGetString(link, &s);
        !           204:         zz = new_cmo_zz_set_string(s);
        !           205:         MLDisownString(link, s);
        !           206:     }
        !           207:     return zz;
        !           208: }
        !           209: \end{verbatim}
1.1       ohara     210:
1.9     ! ohara     211: つまり、Mathematica から整数を文字列として受け取り、その文字列を
        !           212: \oxmath が CMO\_ZZ に直している。
1.6       ohara     213:
1.9     ! ohara     214: % このように基本的に MathLink では全てのデータを文字列で受け取るしか方法は
        !           215: % ない。どのような種類のデータであるかは受け取る前に知ることはできる。デー
        !           216: % タの型は、MLTKERR(エラー), MLTKINT(整数), MLTKSTR(文字列), MLTKREAL(実数),
        !           217: % MLTKSYM (シンボル), MLTKFUNC(関数) のいずれかである。このような事情で
        !           218: % Mathematica から受け取ったデータは基本的に CMO\_STRINGとしてスタックに積
        !           219: % まれるので、クライアント側でその文字列の解釈をする必要がでてくる。しかし
        !           220: % ながら、全ての MathLink オブジェクトが文字列に変換できるわけではないので、
        !           221: % その取り扱いには注意を要する。
1.1       ohara     222:
1.8       ohara     223: \section{\oxmath への計算中断機能の実装}
                    224:
                    225: \noindent
                    226: {\bf 注意: {\tt ox\_math\_interruption.tex}
                    227: に Risa/Asir Conference (2003) での講演原稿がある.}
                    228:
                    229: OpenXM プロトコルは、エンジンに対して、計算中断機能を要求する。\oxmath
                    230: のような wrapper プログラムでは、そのような機能を実装するのは一般には難
                    231: しいが、MathLink には Mathematica Book~\cite{Wolfram-1996} に書かれてい
                    232: ない機能があり(\cite{MathSource-Google1}, \cite{MathSource-Google2},
                    233: \cite{Math-Output1})、そのひとつを用いて、\oxmath に計算中断機能を実装し
                    234: た。この節では、その実装について説明する。
                    235:
                    236: Mathematica Kernel に対する割り込みは、
                    237: \begin{enumerate}
                    238: \item MLPutMessage で Mathematica Kernel に MLInterruptMessage を送る。
                    239: \item 通信路の後始末を行い、最終的に ReturnPacket[\$Aborted] を受け取る。
                    240: \end{enumerate}
                    241: ことでなされる。
                    242: MLPutMessage は MathLink の非公開関数でネットワーク透過性はない。
                    243: Unix と Windows では異なるが、Unix の場合、MLInterruptMessage の実体は
                    244: SIGINT である。
                    245: 通信路の後始末には、{\bf Mathematica Kernel のバージョン依存性がある}ので、
                    246: それを回避すると、結局、次の手順になる。
                    247: \begin{enumerate}
                    248: \item MLPutMessage(link, MLInterruptMessage)
                    249: \item MenuPacket[1,"Interrupt> "] を受け取れば計算が中断されている
                    250: \item MLPutString(link, "$\backslash$n")
                    251: \item MenuPacket[0,"Interrupt> "] を受け取る
                    252: \item MLPutString(link, "a")
                    253: \item TextPacket["..."] を受け取る
                    254: \item EvaluatePacket[0] を送って、ReturnPacket[...] をふたつ受け取る。
                    255: 最初のものが ReturnPacket[\$Aborted] である。
                    256: \end{enumerate}
                    257:
                    258: 最後の手順を説明する。
                    259: ここで、ReturnPacket[\$Aborted] が素直に返ってくればいいのであるが、
                    260: バージョン 3.x では返ってくるのに、バージョン4.xでは、何故か、
                    261: 返ってこず、次の計算を行うとき、ふたつまとめて返ってくる。
                    262: よって、ダミーにEvaluatePacket[0] を送るのである。
                    263:
1.1       ohara     264: \section{Mathematica を OX のクライアントに}
1.6       ohara     265:
                    266: OpenXM クライアントは Mathematica の外部プログラム({\tt math2ox}) の形で
                    267: 実現されている。すなわち、Mathematica と math2ox の間は MathLink プロト
                    268: コルで、math2ox と OpenXM サーバの間は OpenXM プロトコルで通信し、
                    269: math2ox が適切に情報を変換しながらやりとりする。その意味で wrapper の一
                    270: 種であるとも言える。
1.1       ohara     271:
1.3       ohara     272: 利用するには、最初に
1.1       ohara     273: \begin{verbatim}
                    274: In[1]:= Install["math2ox"]
                    275: \end{verbatim}
1.3       ohara     276: として、math2ox をロードしなければならない。
1.9     ! ohara     277: Mathematica に新たに定義されるコマンドは、\\
1.5       ohara     278: {\tt OxStart[s\_String], OxStartInsecure[s\_String, p\_Integer, q\_Integer],
1.9     ! ohara     279: \\
        !           280: OxStartRemoteSSH[s\_String, host\_String],
        !           281: \\
        !           282: OxExecuteString[id\_Integer, s\_String],
        !           283: OxParse[id\_Integer, s\_String],
        !           284: \\
        !           285: OxSendMessage[id\_Integer, s\_String],
        !           286: OxGet[id\_Integer],
        !           287: \\
        !           288: OxPopCMO[id\_Integer],
        !           289: OxPopString[id\_Integer],
        !           290: \\
        !           291: OxClose[id\_Integer],
        !           292: OxReset[id\_Integer]}
        !           293: \\
        !           294: の11個である。
1.1       ohara     295:
1.3       ohara     296: math2ox をロードしたら、
1.1       ohara     297: \begin{verbatim}
1.9     ! ohara     298: In[2] := pid = OxStart["ox_sm1"]
1.1       ohara     299: \end{verbatim}
1.3       ohara     300: によって OpenXM サーバに接続する。この場合の接続先は ox\_sm1 である。
1.9     ! ohara     301: 返り値 pid は、セッション番号である。
1.3       ohara     302: もちろん
                    303: \begin{verbatim}
1.9     ! ohara     304: In[2] := pid = OxStartInsecure["water.s.kanazawa-u.ac.jp", 1300, 1400]
1.3       ohara     305: \end{verbatim}
                    306: のようにして、insecure モードで接続してもよい。ただしこの場合は、
                    307: あらかじめ {\tt Run[]} 等で、OpenXM サーバを起動しておかなければならない。
                    308:
                    309: 接続が成功したらデータを送ってみよう。
                    310: \begin{verbatim}
1.9     ! ohara     311: In[3] := OxParse[pid, "(CMO_LIST, (CMO_STRING, "hello world"), (CMO_ZERO))"]
1.3       ohara     312: \end{verbatim}
                    313: のように CMO expression を指定することによって、
                    314: 任意の CMO を送信できる。
                    315: 正しくない CMO の場合には、何も送信されない。
                    316: また、CMO ではなく、
                    317: \begin{verbatim}
1.9     ! ohara     318: In[4] := OxParse[pid, "(OX_COMMAND, (SM_popCMO))"]
1.3       ohara     319: \end{verbatim}
                    320: などとして、OX メッセージの形で記述することもできる。
                    321: 注意しなければならないのは、SM コマンドの場合、OX スタックマシンから
                    322: OX メッセージが送られてくる場合があるが、OxParse[] を用いた場合、
                    323: このメッセージは自動的には受信しない(現在の仕様では)。したがって明示的に
                    324: 受信する必要がある。そのためには
                    325: \begin{verbatim}
1.9     ! ohara     326: In[5] := OxGet[pid]
1.3       ohara     327: \end{verbatim}
                    328: とするだけでよい。返ってくるオブジェクトは CMO に対応するものである。
                    329: \begin{verbatim}
1.9     ! ohara     330: In[6] := OxPopCMO[pid]
1.3       ohara     331: \end{verbatim}
1.9     ! ohara     332: を用いる場合にはもちろん {\tt OxGet[pid]} を呼び出す必要はない。
1.3       ohara     333:
1.9     ! ohara     334: 計算を実行するには {\tt OxExecute[pid, ...]}
1.3       ohara     335: (SM\_executeStringByLocalParser) か、適切な OX メッセージを送信すること。
1.1       ohara     336:
1.3       ohara     337: 計算が終わったら、
1.1       ohara     338: \begin{verbatim}
1.9     ! ohara     339: In[7] := OxClose[pid]
1.1       ohara     340: \end{verbatim}
                    341: とすると、接続が終了する。
                    342:
                    343: \appendix
                    344: \section{付録}
                    345:
                    346: GMP における ``整数型'' {\tt mpz\_t} はつぎのような
                    347: 内部表現を持つ: \\
                    348: まず  {\tt mpz\_t} 型は
                    349: \begin{verbatim}
                    350: typedef struct __mpz_struct mpz_t[1];
                    351: \end{verbatim}
                    352: と typedef されており,
                    353: {\tt mpz\_t} 型の変数は(関数の仮引数でない限り)配列の
                    354: 扱いである. また,
                    355: \begin{verbatim}
                    356: typedef unsigned long int mp_limb_t;
                    357: \end{verbatim}
                    358: と宣言されている場合には,
                    359: 変数 {\tt mpz\_t x} の {\tt x->\_mp\_d} が unsigned long int の
                    360: 配列であり, データの実体である.
                    361: これは整数の最下位4バイトが配列の先頭にくる.
                    362: つまり全体としては``リトルエンディアンっぽい''が,
                    363: 各 unsigned long int はマシンのネイティブな integer である.
                    364: つまり, GMP の内部表現はマシン依存となっている.
                    365:
                    366: \begin{thebibliography}{99}
                    367: \bibitem{Openxxx-1998}
                    368: 野呂正行, 高山信毅.
1.4       ohara     369: {Open XM の設計と実装 --- Open message eXchange protocol for Mathematics},
1.8       ohara     370: November 22, 1999, Revised March 4, 2005.
1.1       ohara     371: \bibitem{Ohara-Takayama-Noro-1999}
                    372: 小原功任, 高山信毅, 野呂正行.
1.4       ohara     373: {Open asir 入門}, 1999, 数式処理, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG 出版, Tokyo).
1.1       ohara     374: \bibitem{Wolfram-1992}
                    375: ウルフラム.
                    376: {Mathematica (日本語版)},
                    377: アジソンウエスレイ, 1992.
                    378: \bibitem{Wolfram-1996}
                    379: Stephen Wolfram.
                    380: {The Mathematica Book}, Third edition,
                    381: Wolfram Media/Cambridge University Press, 1996.
                    382: \bibitem{miyachi-1998}
                    383: 宮地力.
                    384: {Mathematica によるネットワークプログラミング},
                    385: 岩波コンピュータサイエンス,
                    386: 岩波書店, 1998.
1.8       ohara     387: \bibitem{MathSource-Google1}
                    388: Todd Gayley.
                    389: [mg17015] in MathArchive,
                    390: 1999 April.
                    391: \bibitem{MathSource-Google2}
                    392: 昔の MathLink にあった MLSignal の解説.
                    393: (以前、Google のキャッシュにあったが、もうない)
                    394: \bibitem{Math-Output1}
                    395: mathlink.h, libMLa のシンボル表, mprep の生成するソース.
1.1       ohara     396: \end{thebibliography}
                    397:
                    398: \end{document}

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