Paraisoうごきはじめた
Paraisoでとにかく何か動いているように見えるものが生成できるようになりました。
https://github.com/nushio3/Paraiso/
遊び方はREADMEに書いてあります。ライフゲームのルールを記述したソースはこれで、本質的なとこだけ抜き出すと
adjVecs :: [Vec2 Int] adjVecs = zipWith (\x y -> Vec :~ x :~ y) [-1, 0, 1,-1, 1,-1, 0, 1] [-1,-1,-1, 0, 0, 1, 1, 1] buildProceed :: Builder Vec2 Int () buildProceed = do cell <- bind $ load Rlm.TLocal (undefined::Int) $ Name "cell" neighbours <- fmap (map return) $ forM adjVecs (\v -> shift v cell) num <- bind $ foldl1 (+) neighbours isAlive <- bind $ (cell `eq` 0) && (num `eq` 3) || (cell `eq` 1) && (num `ge` 2) && (num `le` 3) store (Name "cell") $ select isAlive (1::BuilderOf Rlm.TLocal Int) 0
です。おぼろげに、adjVectsでずらして、足し算して、おなじみの生存判定をして、結果を返してることが分かると思います。あと、所々明示的に型を書かないといけないのが残念です。
残念ながら、今は未実装の部分もあり、強烈な見落とし(グラフのエッジの順番って保存されない・・・)があったのをadhocに誤魔化した所あり、そもそもあんまり大したコードは生成できず、Cのコードを生成してる部分はgdgdで、GPUとかMPI対応もまだまだこれからです。そもそも上のコードだってbindとかsequenceAとかfmapとかforMを適切に挟まないと動かないので使えたもんじゃなくて、QQでもっと手軽にしたいところです。自慢できるところがあるとすれば任意のn次元配列に対応してるところとか(THとか使わずに)、中間表現の1行ごとにメモリに置くか計算して済ますか選べるのでこう見えて指数関数的パターン数のコードが生成可能で、自動最適化への道がわずかに開きかかっていることぐらいでしょうか。
が、今までにないアプローチで多次元配列を操作するコードが生成できたということを今日は記念したいと思います。