分散並列Lisp　中間報告

# 概要
ISLisp基準、準拠のEasy-ISLispはver5.0において分散並列機能を追加することを計画しています。現在、ver4.5においてその機能の基本部分が機能するようになりましたのでご報告します。


# 目的
現在のコンピューターはマルチコア化しています。動作クロックの高速化は上限に達しつつあり、これを補うために並列にその道を見出しているようです。量子コンピューターはブレークスルーですが、それが実用になるのはまだまだ先のことと思います。この間、現在のノイマン型デジタルコンピューターが現役となるでしょう。

現在、流行のプログラム言語において種々の並列化が試みられています。プログラム言語は流行りすたりがあり、ひととき瞬いた後でいつのまにか消え去っているものも多くあります。今、主流の言語も将来、どうなるかは定かではありません。一方。Lispは現在、主流の言語ではありませんが、60年以上の歴史があります。Lispは数学に根差しており今後もしぶとく生き残ることでしょう。この言語で並列計算の経験を積んでおくことは、良い経験になると思います。枝葉末節のことではない並列計算の基本的なことの経験は将来においても色褪せることはないと私は考えました。


# 分散の仕組み
TCP/IP通信を利用して複数のコンピューターを接続します。1台の親Lispから計算を分解して複数のコンピューターに仕事を依頼します。

![dp1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/2c40f11a-83a4-79c6-dc2b-54405103d589.png)


親Lispは並列計算したいプログラムを子Lispに一斉に転送します。さらに一斉にコンパイルし、loadします。これらを親Lispから操作します。このために次の拡張機能を用意してあります。


〇 eisl -n  -nオプションにより子Lispを起動します。これにより子Lispはネットワークモードで動作します。

〇 (dp-create c0 c1 ...cn)   子機のIPアドレスを親Lispに与えてTCP/IP通信を確立する。

〇 (dp-let forms body)  let構文の分散並列版です、

〇 (dp-transfer fn)  ファイルfnを与えて親機からすべての子機にファイルを転送します。

〇 (dp-compile fn)  ファイルfnを親機、子機においてコンパイルします。

〇 (dp-load fn)  ファイルfnを親機、子機においてloadします。

〇 (dp-system n sexp)  ｎ番目の子LispにS式を評価させます。子機のテストに使います。

〇 (dp-close) 子機に終了命令を送り、通信をクローズします。


# 動作例


- 子機においてネットワークモードでLispを起動します。

![bandicam 2024-07-07 10-02-34-144.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/0a0363dc-8896-82ad-cdc9-73f8cd5f833c.jpeg)



- 親機を起動します。このときコンパイラも使いたいので-cオプションで起動します。

![bandicam 2024-07-07 10-03-02-164.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/c4694349-8613-3d71-eec0-0ad5bf9b1130.jpeg)


- (dp-create  c0 c1)を使って2台の子機との通信を確立させます。

![bandicam 2024-07-07 11-36-35-094.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/8a6b12ca-cfb6-9115-9fd5-cf0f51449280.jpeg)



- (dp-transfer fn)を使ってプログラムファイルを全部の子機に転送します。
![bandicam 2024-07-07 11-21-41-395.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/02c2e1ad-9c14-2808-d269-80fdc7dcb1b5.jpeg)


- (dp-compile fn) を使ってプログラムファイルをコンパイルします。
![bandicam 2024-07-07 11-22-25-403.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/1ef0b44e-ef6f-bc13-b315-11ad6405b6d6.jpeg)



- (dp-load fn) を使ってコードを親機、子機のすべてでloadします。

![bandicam 2024-07-07 11-23-05-635.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/76929924-e36f-bc89-fd14-06abe7885696.jpeg)



 - 親機で計算テスト
dp-letを使った分散並列が機能していることを確かめます。

![bandicam 2024-07-07 11-40-15-085.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/86193318-6484-f2e9-8364-4ca608f60a3f.jpeg)

![bandicam 2024-07-07 11-25-43-063.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/bf2ddd29-e7e4-048c-1c61-14cd4a6f275d.jpeg)


子機にいおいては親機とのやりとりがターミナルに表示されています。

![bandicam 2024-07-07 15-58-14-060.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/1e01fb0d-28a8-3e2e-7b8b-3eb90a4a57d1.jpeg)




# 今後の展望

計画している並列機能は下記の通りです。

(dp-exec x0 x1 ... xn)  単純並列実行

(dp-part t x0 x1 ... xn)　部分並列実行

(dp-part nil x0 x1 ... xn) 部分並列実行

(dp-call fn a0 a1 ... an) 並列構文

(dp-report str) 子機から親機の端末に文字列strを表示する。


# 将来課題
今のところイミュータブルなデータでの実行を考えています。大域変数への破壊的代入、参照を許すこととするととても複雑になります。子Lispが大域変数を書き換えた場合には競合が起こらないように制御しながら各機の大域変数を書き換えなくてはなりません。

当面、決定性の問題、例えばパズルを解くことですとか、クイックソートのように完全に並列分離しているアルゴリズムに絞って計算が機能するのかを確認します。

流体力学の計算のようなことをやろうとするとMPIのような仕組みが必要となります。これは必要に迫られたときの将来課題としたいと考えています。

# 実装
Easy-ISLispはgithubにおいてあります。BSD2ライセンスです。ご自由にお試しください。
https://github.com/sasagawa888/eisl

# 蛇足
以下は個人的意見です。Lisperの中には昔のことに異常に拘る人がいます。あるいはEmacsなどツールに異常に拘る人がいます。古きを訪ねて新しきを知ることはとても重要なことです。古い知恵が未来を切り開くかもしれません。過去だけにしがみついていたらもうそれ以上の発展はありません。Lispには未来言語であってほしいと私は願っています。