Amazon Braketで量子コンピュータをはじめよう！

# Amazon Braketがpublicになりました
AWSの量子コンピュータ・サービスであるAmazon Braketはprivate previewとして運用されていましたが、publicになり誰でも使えるようになりました。

この記事は、ひとまずAmazon Braketを触ってみよう、という趣旨です。
この記事では「量子コンピュータって何？」という点は説明しません。(すみませんが、これを書き始めると随分長くなってしまうので、書籍や他の記事などを参照してください)
また、AWSの利用経験が多少ある人を前提にしています。
(2020/08/14時点の情報にもとづいています)

- Amazonのプレスリリースです。
  https://press.aboutamazon.com/news-releases/news-release-details/aws-announces-general-availability-amazon-braket

- Developer Guideが公開されているので、詳しい内容はこちらを参照するのが良いと思います。
  https://docs.aws.amazon.com/braket/latest/developerguide/what-is-braket.html

- 料金表はこちらにあります。
  https://aws.amazon.com/jp/braket/pricing/

Amazon Braketでは複数の会社が提供する量子コンピュータを使い分けできます。
Rigettiが提供する量子コンピュータは1回実行すると、$0.65ですね(標準的な1000ショット前提)。  

　1タスク(\$0.30000) + 1000ショット(\$0.35000) = \$0.65000

IonQが提供する量子コンピュータはもうちょっと高くて、1ショットが$0.01000となっています。
(「ショット」という量子コンピュータの概念があるのですが、ここではひとまず「そういうのがあるんですね」くらいでよいです)

Amazon Braketのアイコンは、チップの周りを量子が回っているイメージのようです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/385f6e65-c98a-7e3a-488d-8df128662e9e.png" width=20%>


# ログイン～バケット作成
というわけで、ひとまず触ってみましょう。
Amazon SageMaker(機械学習のサービス)と似た操作の流れなので、Amazon SageMakerの利用経験があると量子コンピュータが初めての人でもなじみやすいかもしれません。

Amazonのブログにも始める際の手順が書いてありますので、これにしたがって進めるのがよいかもしれません。

- Amazon Braket – Go Hands-On with Quantum Computing(英語)  
  https://aws.amazon.com/jp/blogs/aws/amazon-braket-go-hands-on-with-quantum-computing/

- Amazon Braket — 量子コンピューティングを実践(日本語)  
  https://aws.amazon.com/jp/blogs/news/amazon-braket-go-hands-on-with-quantum-computing/


Amazon BraketのAWSコンソールはこちらからログインできます。
https://us-west-2.console.aws.amazon.com/braket/home


ログインすると、Amazon Braket用のS3バケットを作成するかどうか、アカウントの権限をどうするか聞かれます。
どうしてS3が出てくのかと言うと、Amazon Braketは実行結果をS3に保存するためです。
利用規約をチェックするのも忘れずに。
![braket1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/cb3446b6-b470-85a6-d1a6-0cee49c1898e.png)

ログインすると次の画面が出てきます。
画面左側のメニューの「Devices」をクリックしても行けます。
![braket2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/af743d79-e1ba-e6e9-1bc1-2ba00a374a37.png)

次の量子コンピュータを利用できます。

| 提供会社 | デバイス名 | 物理方式 | 利用可能リージョン | 利用可能時間 |
|:-----------|:------------|:-------------|:-------------|:-------------|
| D-Wave | DW_2000Q_6 | 量子アニーリング | us-west-2(オレゴン) | いつでも利用可能 |
| IonQ | ionQdevice | イオントラップ量子コンピュータ | us-east-1(バージニア北部) | 日本時間で月～金の22時～翌6時 |
| Rigetti | Aspen-8 | 超伝導量子コンピュータ | us-west-1(北カリフォルニア) | 日本時間で火～土の0時～4時、6時～8時 |
| AWS | DefaultSimulator | シミュレータ | ローカルで動くため、リージョンに関係なく動作する | いつでも利用可能 |
| AWS | SV1 | シミュレータ | 全リージョン | いつでも利用可能 |

**デバイスによって利用可能時間が異なるため、注意してください。**
次のページに説明がありますが、ライブラリ(Amazon Braket SDK)側で適切なリージョンを判断して送信するため、リージョンはあまり気にしなくてよいです。
https://docs.aws.amazon.com/braket/latest/developerguide/braket-regions.html

# デバイス(量子コンピュータの実機)についての説明

この記事では、Rigettiのデバイスを利用します。
「Devices」の画面から「Rigetti」をクリックします。
Rigettiのデバイスの説明やキャリブレーション情報を記載した画面が表示されます。

- 概要

利用可能なリージョン、デバイスのarnなどの情報が書いてあります。
![braket3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/6d4bda6f-ed5e-4a3d-b5b9-7298e272e580.png)

- デバイスのトポロジー情報
重要な情報なのですが、はじめて実行するときは気にしなくてよいです。
量子コンピュータに慣れてきたら気にします。
![braket4_topology.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/b9dc9d11-417f-aec3-9152-e231c0736abd.png)

- キャリブレーション情報
これも重要な情報なのですが、はじめて実行するときは気にしなくてよいです。
量子コンピュータに慣れてきたら気にします。
![braket5_calibration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/b88e26dc-d227-1052-7e1d-2b117607ba85.png)

# notebookの起動

ひとまず実行してみましょう。
画面左のメニューにある「Notebooks」にある「Create notebook instance」をクリックしましょう。(こういうところ、Amazon Sagemakerに似ていますね)
![braket6_menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/048c3f80-cdfd-a3e0-801c-d0a4b0be0dad.png)

notebookを作成する画面になりました。

![braket7_createnotebooks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/d2ee8452-e636-232e-7426-819b34d6bc82.png)

インスタンス名はアカウント毎にリージョン内でユニークである必要があります。
notebookにアクセスするためのURLは「<インスタンス名>.notebook.<リージョン名>.sagemaker.aws」となります。
(内部的にAmazon Sagemakerを流用しているんですね😄)

インスタンスタイプは、ひとまず「ml.t2.medium」にしました。
設定を決めたら、画面右下にある「Create notebook instance」をクリックしましょう。

すると、先ほどのNotebooksの画面に戻ります。
裏でインスタンスの作成が行われています。
しばらくすると「status」が「InService」になるので、それまで待ちましょう。
(画面は自動リフレッシュしないようなので、リフレッシュのボタンを押しましょう)

**「InService」の間はEC2の利用料が課金されますので、利用後は停止するのを忘れずに。**
![braket7_createnotebooks2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/c823a720-9d61-85ee-b9d9-73c8a5d6eaff.png)

# notebookから量子コンピュータを実行

「InService」になったら、「Name」か「URL」をクリックしましょう。


Jupyter Notebookの画面が表示されます。
![braket8_jupyter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/72f869f3-99fa-28de-d9d8-453b1cacf539.png)

ひとまず、examplesとして提供されているnotebookを実行してみましょう。
様々なデバイスのnotebookが混ざっているのと、はじめて量子コンピュータに触る人向けの内容じゃないので、分かりづらそうですね。。。
きっと、今後分かりやすいnotebookが追加されると思います。
この記事ではRigettiのデバイスを触りたいので、次のディレクトリに移動して「Running_quantum_circuits_on_different_devices.ipynb」というnotebookを開きましょう。

> [Braket examples] > [simple_circuits_algorithms] > [Backends_Devices] > [Running_quantum_circuits_on_different_devices.ipynb]

「Running_quantum_circuits_on_different_devices.ipynb」を開くと、次のような画面が表示されます。
量子コンピュータをはじめて触る人には何を言ってるのか分からない内容かもしれませんが、あまり気にしなくてよいです。
必要になったら、ちゃんと読みましょう。
(このnotebookは基本的な操作方法が書いてあるので、ガッツリ触る前には理解しておいた方が良さそうです)
![braket11_jupyter4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/a93d0fc9-26c4-7e54-e70f-2122106b865b.png)

2番目のセルに設定を入力する箇所があるので、変数my_bucketに「ログイン～バケット作成」で作成したバケット名を指定します。

```python:In[2]
# set up S3 bucket (where results are stored). Change the bucket_name to the S3 bucket you created.
aws_account_id = boto3.client("sts").get_caller_identity()["Account"]
my_bucket = f"★書き換える★" # the name of the bucket
my_prefix = "simulation-output" # the name of the folder in the bucket
s3_folder = (my_bucket, my_prefix)
```
まずは、1番目と2番目のセルを実行します。

さあ、それでは、Rigettiの量子コンピュータを実行してみましょう！
このノートブックの前半はシミュレータの操作なので、飛ばしてしまい、中盤にある「Quantum Hardware: Rigetti」までスクロールしましょう。
「Quantum Hardware: Rigetti」の所に実行可能なセルが2個あるので、これを実行します。
うまくいくと、次のようになるはずです。(セキュリティの都合で一部を黒塗りにしています)
![braket12_jupyter5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/f6aa3f7b-71d3-3b6f-09b7-d14777b1be4b.png)

最初のセルを実行すると、タスクが作成され、Rigettiの量子コンピュータに送信されます。
「Status of task: CREATED」と表示されればOKです。

非同期で実行しているため、しばらくしてから次のセルを実行します。
「Status of (reconstructed) task: COMPLETED」と表示されれば実行完了です。

また、実行結果はjson形式でS3に保存されます。

ただ、これだと実行結果が分からないので、次のセルを作成して実行してみましょう。

```python:
result = rigetti_task.result()
counts = result.measurement_counts
print(counts)

# plot using Counter
plt.bar(counts.keys(), counts.values());
plt.xlabel('bitstrings');
plt.ylabel('counts');
```

次のように、Counterの値とヒストグラムが表示されればOKです。

![braket13_jupyter6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/a978d8e6-8b6e-6738-a11e-23444d1106e9.png)

量子コンピュータの特性上、実行結果は確率的に変化するため、Counterの値は実行するたびに変わります。
この場合は正しく動作すれば「00」と「11」の値が大きくなります。

これで、Rigettiの量子コンピュータを実行できました。

# notebookインスタンスを立てずに実行する場合

「Amazon Braket Python SDK」が公開されているため、これを使います。
対応しているPythonのバージョンは3.7.2以降です。

- PyPI
  https://pypi.org/project/amazon-braket-sdk/

- GitHub
  https://github.com/aws/amazon-braket-sdk-python

- Read the Docs
  https://amazon-braket-sdk-python.readthedocs.io/

「Amazon Braket Python SDK」以外だとboto3も対応してますが、実行するにはちょっと大変そうなAPIに見えます。

- Developer Guide
  https://docs.aws.amazon.com/braket/latest/developerguide/braket-using-boto3-client.html

- boto3のドキュメント
  https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/braket.html

LocalSimulatorというのを使うと、量子コンピュータもS3も使わず、ローカルでシミュレータとして動作します。
次のページの「Usage」に書いてある実装方法が分かりやすいです。

- GitHub: amazon-braket-default-simulator-python  
  https://github.com/aws/amazon-braket-default-simulator-python

LocalSimulatorの実行方法をQiitaに書いたので、こちらを見てもよいと思います。

- Amazon Braketで無料の量子コンピュータ・シミュレータを使う  
  https://qiita.com/snuffkin/items/977dc1ec1b67a4d1cf20


# おわりに

というわけで、Amazon Braketにひとまず触ってみました。
Amazonが量子コンピュータのマネージド・サービスを出したことにより、QaaS(Quantum as a Service)がさらに進みますね。
量子コンピュータに触る人が増えそうで楽しみです。

最後にもう一度言いますが、**「InService」の間はEC2の利用料が課金されますので、利用後は停止するのを忘れずに。**