Elixir での量子コンピューティングの研究の展望

(この記事は[「量子コンピュータ Advent Calendar 2018」](https://qiita.com/advent-calendar/2018/quantum)25日目です)

[「量子コンピュータ Advent Calendar 2018」](https://qiita.com/advent-calendar/2018/quantum)24日目は @piacere_ex さんの[「ElixirでTDDしつつ量子コンピュータシミュレータを作ってみた」](https://qiita.com/piacere_ex/items/d49c4952a2fb75ef74d1)でした。

この記事はその続きで，私たち [fukuoka.ex](https://fukuokaex.fun) が考えている「Elixir での量子コンピューティングの展望」について語りたいと思います。技術ポエムです，すみません。

# 量子コンピューティングの研究トレンドと本記事の位置付け

2018年8月に仕入れた情報によると，量子ゲート方式の量子コンピュータシミュレータの研究の世界的なトレンドは，主に，**いかに大きな量子ビット数を実現できるか，ある量子ビット数の計算をいかに高速に実行するか**，という点にあるそうです。

量子ゲート方式の量子コンピュータシミュレータは，大まかには量子ビットで表される組み合わせを総当たりで評価するというような原理になります。量子ビットが増えれば増えるほど，指数関数的に必要となるメモリが増えます。大きな量子ビット数を実現するためには，これに耐えられるように設計するということが肝要になります。

また，量子ビットで表されるビットの組み合わせを GPU を使って並列計算することで，高速実行するというのが研究のトレンドになっています。

このように，量子コンピュータシミュレータの研究は，パワーゲーム的な感じになっています。

一方で，量子コンパイラの研究は，まだそれほど進んでいないそうです。影響力ある研究テーマになりそうなのは，**ある量子コンピュータのプログラムについて，できるだけ量子ビットを節約するように最適化する**というようなテーマが考えられます。

私自身は，量子コンパイラにおける最適化の研究の方に，より興味と関心があります。しかし，Elixir を用いた量子コンピューティングは，ようやくシミュレータの開発に着手できたという段階なので，現実的に着手可能なのは，ある量子ビット数の計算をいかに高速に実行するか，という研究になるだろうと考えています。

この記事では，私たちが研究開発を進めている **Hastega** (ヘイスガ) という GPU を含む超並列高速実行処理系を量子コンピュータシミュレータに適用することについて，まずは考えたいと思います。

# Hastega

Hastega では次のような Elixir の MapReduce スタイルのプログラムコードを GPU で駆動します。 

```elixir
1..1_000_000
|> Enum.map(foo)
|> Enum.map(bar)
|> IO.inspect
```

* 1行目の`1..1_000_000`は，1から1,000,000までの要素からなるリストを生成します。なお，数字の間の`_`(アンダースコア)によって，数字を分割するコンマを表します。
* 2,3行目の先頭にある`|>`は**パイプライン演算子**で，パイプライン演算子の前に書かれている記述の値を，パイプライン演算子の後に書かれた関数の第1引数として渡します。すなわち，このような記述と等価です。`Enum.map(Enum.map(1..1_000_000, foo), bar)`
* 2,3行目に書かれている `Enum.map`は，第1引数に渡されるリスト(など)の要素1つ1つに，第2引数で渡される関数を適用します。ここでは関数 `foo` を各要素に適用した後，関数 `bar` を各要素に適用します。
* もし，`foo`が2倍する関数で，`bar`が1加える関数だった時には，これらの記述により，2倍してから1加える処理を1から1,000,000までの要素に適用したリスト，`[3, 5, 7, ...]` を生成します。

GPU が採用する **SIMD** (単一命令列／複数データ) アーキテクチャは，**単純で均質で大量にあるデータ**を**同じような命令列**で処理する場合に適合するように設計されているので，このような場合に最も高速化できます。先ほどのプログラム例だと，`1..1_000_000` の部分が**単純で均質で大量にあるデータ**に，`foo` と `bar` が**同じような命令列**に，それぞれ該当します。したがって，このような **Elixir の MapReduce スタイルのプログラムコードは，GPUで並列化しやすい**ということになります。

Hastega のプロトタイプ実装での評価結果ですが，Elixir からの速度向上が約4〜8倍，　Python の CuPy と比べて約3倍以上高速でした。発表資料(論文，プレゼンテーション，ポスター)を下記に示します。

[![Hastega: Elixirプログラミングにおける超並列化を実現するためのGPGPU活用手法](https://qiita-image-store.s3.amazonaws.com/0/55223/b81d5c4c-f8d5-387f-571d-e8251ce4509e.png)](https://zeam-vm.github.io/papers/GPU-SWoPP-2018.pdf)

[![Hastega: Elixirプログラミングにおける超並列化を実現するためのGPGPU活用手法](https://qiita-image-store.s3.amazonaws.com/0/55223/2fb20104-f286-53ae-456f-58abbe7f3fc7.png)](https://zeam-vm.github.io/GPU-SWoPP-2018-pr/#/)

[![Hastega: Elixirプログラミングにおける超並列化を実現するためのGPGPU活用手法](https://qiita-image-store.s3.amazonaws.com/0/55223/95ec444a-889c-e0d2-9e1d-8b24d84cb485.png)](https://zeam-vm.github.io/papers/SWEST_Hastega.pdf)

今度，[Lonestar ElixirConf 2019 (2月28日〜3月2日 テキサス州 オースティン)](https://lonestarelixir.com/)でも発表してきます！
 
[![Presentation at Lonestar ElixirConf 2019](https://qiita-image-store.s3.amazonaws.com/0/55223/140a46a9-527b-66e2-a048-aee3d66a3ee0.png)
](https://lonestarelixir.com/2019/speakers/21#susumu-yamazaki)

Hastega は次のような順番でリリースしていく予定です。

1. サーバー側の x86_64 アーキテクチャの CPU の SIMD 命令を駆動
2. サーバー側の GPU を駆動
3. サーバー側の ARM の SIMD 命令を駆動
4. クライアント側の GPU を駆動 (参考記事: [「WebGL / WebGPU + Hastega / Elixir / Phoenix で分散／エッジ・コンピューティング」](https://qiita.com/zacky1972/items/4c6fbd73a6fe7fd2265f))
5. クライアント側の CPU の SIMD 命令を駆動

Hastega の実装方針について興味をお持ちでしたら，下記を参照ください。

[ZEAM開発ログ: Elixir マクロ + LLVM で超並列プログラミング処理系を研究開発中](https://qiita.com/zacky1972/items/cc88260a3c93c9f71317)

# 量子コンピュータシミュレータへの Hastega の適用

@piacere_ex さんの[「ElixirでTDDしつつ量子コンピュータシミュレータを作ってみた」](https://qiita.com/piacere_ex/items/d49c4952a2fb75ef74d1)が採用している [Numexy](https://hex.pm/packages/numexy) と [ComplexNum](https://hex.pm/packages/complex_num) を Hastega 対応させられるかどうかが鍵になってきます。

@yujikawa さん作の行列計算ライブラリ [Numexy](https://hex.pm/packages/numexy)は，Enum を使った MapReduce スタイルで記述されていますので，Hastega で容易に高速化できることでしょう。

一方，[ComplexNum](https://hex.pm/packages/complex_num) はマクロを多用しており，容易には Hastega により高速化できない可能性もあります。その場合には，[ComplexNum](https://hex.pm/packages/complex_num) 相当のインタフェースを持ち Hastega に対応させたようなライブラリを開発する必要があるでしょう。

Hastega により，サーバー側・クライアント側の CPU / GPU を総動員して計算できるようになります。この機能を用いて，量子コンピュータシミュレータの高速化を図りたいと思います！

# おわりに

この記事では，「Elixir での量子コンピューティングの研究の展望」と題して，主に Hastega を用いた量子コンピュータシミュレータの高速化について展望をお話ししましたが，いかがだったでしょうか？

今後も，Elixir を用いた量子コンピューティングのための技術の研究開発を続けて行きますので，ご期待ください！

私が次にアドベントカレンダーの記事を書くのは，いよいよフィナーレ，[「Elixir Advent Calendar 2018」](https://qiita.com/advent-calendar/2018/elixir)25日目，[「Hastega / micro Elixir / ZEAM の実装戦略〜 Erlang VM からの円滑な移行を見据えて」](https://qiita.com/zacky1972/items/73bd91489fd5e08bbf16)です。お楽しみに！