Langphilia! / KL1 / Distributed KL1 / DKLIC4, 2002-01-11

DKLIC v4: 宣言型広域分散計算環境

従来の分散型言語処理系や分散ミドルウェアは手続き型言語の拡張であり、 逐次プログラムのシームレスな分散化が行えない。
並行論理型言語KL1は、


DKLICとは

DKLICはKL1に基づく宣言型広域分散計算環境である。

+----------+
|   O.............................
|   .      |                  +--.-------+
|   .      |                  |  .       |
|   ..O    |                  |  O       |
|     .    |                  |          |
|     .    |   +----------+ ......O      |
+-----.----+   |          | . |       O  |
      .        |  O.......... |          |
      .        |          |   +----------+
      .............O      |
      .        |          |
      ............O       |
               +----------+

+-+
| |  ホスト
+-+

O    プロセス
...  通信路

宣言型で楽なネットワークプログラミング。 非決定的な通信順序・同期の抽象化。


ホスト間通信の仕組み

ユーザプロセスは実行系 DKLIC Runtime にホスト間通信を要求する。 Runtimeはユーザプロセスの要求に応じてソケットを管理する。

+----------+      +----------+
|          |      |          |
| Runtime ========== Runtime |
|    .     |      |     .    |
|    .     |      |     .    |
|    O     |      |     O    |
|          |      |          |
+----------+      +----------+

+-+
| |  ホスト
+-+

O    ユーザプロセス
...  通信路
===  ソケット

方針:単純な実装

DKLIC言語処理系の構成

現在のDKLICは、KLIC上のミドルウェアであり、 実行時ライブラリとしてKL1 (, C) で記述する。
KL1 program  KLIC  C program   cc   binary

                   Runtime/C -----> Runtime/bin
Runtime/KL1 -----> Runtime/C -----> Runtime/bin
user   /KL1 -----> user   /C -----> user   /bin

DKLIC Runtimeの組み込みサーバ

基本サーバ

拡張サーバ

Layers

  1. machine, IP, ethernet
  2. unix, TCP, socket
  3. klicio, KLIC実行系
  4. modeio, 変数表, 基本サーバ
  5. 拡張サーバ
  6. ユーザ定義サーバ
  7. アプリケーション

組み込みサーバへのメッセージ

unix, klicio Stream

+stdin / +stdout / +stderr -Result
Result = normal(^File) 標準入力・出力・エラー出力 File: file_ioサーバを開く
+connect2 +inet(+Host, +Port) -Result
Result = normal(^I, ^O) 手続き型ソケット : file_ioサーバを開く
+bind +inet(+Port) -Result
Result = normal(^ServSock) 手続き型サーバソケット ServSock を開く

dklic Local

+bind +inet(+Port) -Result
Result = normal(^ServSock) 宣言型サーバソケット ServSock を開く
+connect +inet(+Host, +Port) -Result
Result = normal(^Sock) 宣言型ソケット Sock を開く

ServSock

+accept -Result
Result = normal(Sock) 宣言型/手続き型ソケット Sock を開く
+accept2 -Result
Result = normal(^I, ^O) 手続き型ソケット : file_ioサーバを開く

^file_io

naming

        検索   通信
unix     --    low  Port -> ServSock  Host:Port -> file_io
dklic    --   high  Port -> ServSock  Host:Port -> Stream
naming  high   --   ID, Host:Port -> 0    ID -> Host:Port

exec

sandbox

agentspace

    N1                       N2
+-----------+           +-----------+
|  dklic ================== dklic   |
|    .      |           ..../ .     |
|    . L1   |    R...../|     .     |
|    .      ...../      |     . L2  |
|    ....../|           |     .     |
|    O........................O     |
+-----------+     S     +-----------+


:                       :
dklic(L1),              dklic(L2),
                        L2=[bind(SS)],
L1=[connect(R)@N2],     SS=[accept(S)|..],
S=[request(Answer)|..], service(S)..
:                       :

v3までの問題点

未定義変数の同一性検出

  1. p(X,Y) :- X=Y | ... は不可能
    ← 未定義変数同士の単一化によって待ちゴール [Inside KLIC] を起こすのは、 メリットが少なくコストパフォーマンスが低い。
    → ユーザプロセスの待つ変数は具体化されるべき(dklicはシステムプロセス)。
  2. variable:unbound/2 - GCによって変数のアドレスが変わってしまう [runtime/var.kl1, unbound.kl1]
    → GCのタイミングを検出できないか?
  3. Generic Object - 未定義変数同士の同一性検出によって、 変数表エントリの単一参照性が失われる
    → dangling referenceが起こらないことを保証する分散GCが必要
    +------------------+   X=[]     +-----+
    |                  |----------->|     |
    | append([],[a],Z) |   Z=Y      | Z=Y |
    |                  |<-----------|     |
    +------------------+            +-----+
    
  4. 未定義変数が移動したことを通知する輸出入プロトコル
    +----------------+ S=[2|S1]  +---+
    | agent([1,2,3]) |---------->| 1 |
    |                |<----------|   |
    +----------------+ S1->node2 +---+
            |
            | S1=[3|S2]          +---+
            +------------------->| 2 |
                                 +---+
    

Generic Object

使い方

3種類

  1. Data Object 具体値を持つ
  2. Consumer Object 書き込みによって処理が行なわれる
  3. Generator Object 読み書きによって処理が行なわれる

KLIC/KL1 プログラムから見ると、Data Object は値, Consumer/Generator Object はゴールの中断原因変数のように見える。

Generic Objectのメソッド

D は Data Object、 C は Consumer Object、 G は Generator Object、 * は3種すべてに共通するメソッド

KLIC処理系で使われているGeneric Object

*.h は include/klic/ に、 *.c や *.kl1 は runtime/ にある。

*.kl1 と *.c の名前が異なるのは、 KLIC翻訳系が生成するファイル名と衝突するのを避けるためだろう。 逆に言うと、*.kl1 と同名の *.c はKLIC翻訳系に生成されたもの。

*.h と *.c の名前が異なるのは意味不明だ。

Generic Objectの作り方

  1. % cp klic-3.003/runtime/gfloat.c test/
  2. % cd test
  3. % sed '/#define GD_CLASS_NAME() float/ s/float/float2/' <gfloat.c >gloat2.c
  4. % klic g_float.kl1 gfloat2.c
  5. % ./a.out

どのようなGeneric Objectが必要か


参考文献


Copyright 2001-2002, TAKAGI Yusuke.