dklic: KL1による分散KL1言語処理系の実装

dklic: KL1による分散KL1言語
処理系の実装
早稲田大学
高木祐介, 上田和紀
並行論理プログラミング言語
(並行制約プログラミング言語)
• Object-basedな微粒度並行言語
– GHC (1985) → KL1 on KLIC (1990’s)
– and many others (Strand, Oz, …)
• 特徴: 論理変数の表現力
– ストリームを用いた非同期メッセージ送信
– 未完成(返信箱つき)メッセージ
– 局所チャネルの動的生成と移送 (cf. π計算(1989))
• 送受信される情報の形態 = (等号)制約
– 例: X=2001, L0=[pop(Y)|L]
プログラミング・イディオム
• 並行オブジェクト
–
–
–
–
動的生成
繰返し
オブジェクトの状態
Object identity
• 通信路
–
–
–
–
–
メッセージ
返信箱
同期・受信
送信
Channel mobility
= ゴール(のマルチ集合)
=
=
=
=
ゴールの起動
末尾再帰
ゴールの引数ベクトル
ゴールのインタフェースである非
局所論理変数
= ストリーム(=リスト)
=
=
=
=
=
ストリームの要素
メッセージの引数
Ask (制約の観測)
Tell (制約の放出)
ストリームの動的生成と送受信
KL1の計算モデル
• 動的プロセス生成+動的ネットワーク構成
• プログラムは節(書換え規則)の集合
節: Head
:-
(テンプレート)
Guard
|
(付帯条件)
Body .
(生成ゴール群)
末尾再帰
Goal
Goal
ゴール群
通信路
Goal
Goal
Goal
なぜKL1ベースの分散処理か?
• 単純な言語である
– 安全性や正当性の検証を伴う分散プログラミングを最
終目標としている
• 論理変数
– ポインタ概念の隠蔽
• 安全性
• 局所的な実体と分散された実体の意味が完全に同一
– 実装の自由度
• データの複製 (replication) が自由
– Update in place による最適化が可能
• 参照数解析 (linearity analysis)
dklic = KLIC+API
• KLIC (http://www.klic.org/)
– KL1-to-C translator + runtime system
– 記号処理言語としては良好な性能
– PVMに基づく分散メモリ並列処理系
• 同一アーキテクチャのPEをまたがる論理変数の分
散実装
– 分散機能はUnixソケットのみ
• dklicではソケットを隠蔽
dklicの目標
• ネットワーク透過な分散計算環境の実現
• 分散実行系によって遠隔ノードに計算依頼
– 遠隔述語呼出し(cf. Java RMI)
– 述語移送(cf. Javaクラスローダ)
– サービス検索(cf. ORB, Jini)
Distributed Runtime System
request
client
Stream server
dklicが前提とする分散環境
• ノード
– 固有の計算空間を持ったプロセス
– アーキテクチャは不特定
• ノード間接続
– 各ノードは通信データの損失や追越しのない
通信路で接続されている(cf. TCP/IP, SSL)
• ノードの把握
– ノード数は不定で、動的に増減する
– 順序付けはできず、識別のみができる
dklic処理系の構成
• 100% KL1による単純な実装
– ノード実行系はKLIC任せ
– 実行系は約400行(第1版は1600行)
• 遠隔述語呼出しを実現
• 述語移送(140行)とサービス検索は試作あり
dklic runtime /KL1 user program /KL1
KLIC compiler
KLIC runtime, dklic runtime, user program /bin
dklicによる遠隔述語呼出しの例
• ping + pingd 逐次部分29行、分散化5行
main(R) :- R=normal(O) |
unix:argv([Host | _]),
% pingd:pingd(Ts) @node(Host),
remote:call(pingd:pingd(Ts), Host),
O = [fwrite(Host), fwrite(": pinging.\n") | O1],
putt(0, 0, Ts, O1).
遠隔述語呼出しの仕組み
ノード毎に1個
KLIC
runtime
pingd(Ts)
stub
ping
KLIC
runtime
skeleton
Ts=[T|Ts1]
pingd
分散論理変数とは
X1
X2
X0
X2
X0
X1
異なるノードの論理変数を対応付けて同じ実体とする。
分散論理変数の実装方針
• 分散論理変数の用途
○ メッセージ通信
• 送信したデータは原則として読まれる
• 1対1、プッシュ型が基本
△ (大きな)データの共有
•
•
•
•
1対多、プル型が基本
プル要求は(KL1では)感知できない
プル型では分散GCが重要
データサーバを要求駆動型に記述すれば,プッシュ型でプル
型などさまざまな配送ポリシーが実現可能
• dklicでは1対1、プッシュ型を基本に
– cf. 並列KLIC (プル型)、Distributed Oz (1対多)
変数表を用いた分散論理変数
の実現
• 変数表
– IDを用いて別ノードの内部変数どうしを対応付け
– (スタブ、スケルトンの子)の対ごとに1対
• 分散論理変数に対する操作
– 生成: 変数表エントリの対の作成
– 具体化: 単一化ゴールの送信 (分散単一化)
– ノード内はKLIC実行系任せ
• 参照の輸出入
– IDの重複を避けてノード別の輸出ID空間
論理変数の輸出入
輸出側がIDを発行
pingd(_0)
ソケット
_0
X0
X
_0
X0
分散論理変数の単一化
[0,X1|X2]=X0
0= X1
_0=[0,_2|_4
]
_0
_2
_0
_2
_4
_4
X0 =[0,X1|X2]
X1 =0
[2,X3|X4]= X2
_2=0
X2
分散論理変数の削除
• 削除しないと
– 変数表は単調増加する
– 内部変数が参照され続け、GCされない
• プッシュ型なので具体化と同時に削除可
能
• IDの再利用
– 使用済みIDを発行ノードに返却する
– 発行側が具体化するなら即時再利用可能
分散変数管理の最適化
_0=[0,_2|_0]
[0,X1|X2]=X0
Y0=[0,Y1|Y2]
_0
_2
_0
_2
0=X1
X2
_2=0
Y1 =0
Y2
第三者による中継
輸出
X
Node1
agent(X,1)
Node0
agent(X,0),
client(X)
間接参照
を輸出
X
Node2
X
直接参照
agent(X,2)
agent(X,N) :- (condition) | agent(X,N+1)@node(N+1).
第三者による中継の排除
• KL1による実装では,第三者による中継を
排除できない
– 未定義変数どうしの同一性を検査できない
• p(X,X) :- true | …
– 変数への参照数を感知できない
• 解決策:
– generic object機構(C言語によるKLICの拡
張)を用いて未定義変数の同一性検査を実装
– 静的参照数解析により,中継ノードに参照が
残らないことを保証
遠隔サーバへの接続
• チャットサーバを遠隔述語呼出しすると
– 複数の接続をまたいでサーバの履歴を残すこ
とができない
– クライアント別の履歴ではチャットにならない
• 既存の遠隔サーバへの接続が必要
– 遠隔述語呼出しによるプロセス生成だけでは
不十分
遠隔サーバの仕組み
KLIC
runtime
chatd(I,O)
stub
skeleton
KLIC
runtime
検索
登録
chat
I, O
chatd
getl, putl
サービス検索
• サービス名によってサービスストリームを
要求する。
• service_name(S)メッセージを適切なノード
の実行系に送信すれば良い。
• 既存のサーバがサービスを生成する。
– 遠隔述語呼出しでは、スケルトンがサービス
を生成する。
まとめと今後の課題
• ネットワーク透過な遠隔述語呼出しを低コ
ストで実現した。
• 今後の課題
– KLICのgeneric object機構と静的解析を用い
た分散変数管理の最適化
– ネットワーク透過な遠隔サーバへの接続の実
現
– 実装および安全性保証への検証技術の適用
その他
• 失敗(例外)の原因
– 単一化の失敗,ゼロ除算,配列参照,メモリ不
足,計算時間超過,node failure,入出力エ
ラー
• 対策はいろいろな角度から
–
–
–
–
静的モード解析(cf. 単一化の安全性)
JIT検証(cf. proof carrying code)
例外処理機構(cf. 荘園)の設計
フォールトトレランス
静的
動的