{ "cells": [ { "cell_type": "markdown", "id": "54db101c-0bfd-46b2-9398-62224f69b512", "metadata": {}, "source": [ "# Amazon Braket で Qiskit を実行する" ] }, { "cell_type": "code", "execution_count": 1, "id": "e861abc5-0649-483e-9eac-04130922464b", "metadata": { "tags": [] }, "outputs": [], "source": [ "# このノートブックの実行料金を見積もるために Braket SDK Cost Tracking を使用します\n", "from braket.tracking import Tracker\n", "t = Tracker().start()" ] }, { "cell_type": "markdown", "id": "3d79f556-9a28-4dc3-9bfc-4d0b55be64aa", "metadata": {}, "source": [ "お客様も、ここ数年で量子コンピュータを学んだ多くの方と同じように、2017 年に初めてリリースされたオープンソースの量子ソフトウェア開発キット (SDK) である Qiskit を使って、量子回路をプログラミングする方法を学んだかもしれません。\n", "[Qiskit-Braket provider](https://github.com/qiskit-community/qiskit-braket-provider/blob/main/docs/tutorials/0_tutorial_qiskit-braket-provider_overview.ipynb) を使えば、[Amazon Braket](https://aws.amazon.com/braket/) のゲートベースのデバイスのどれを使っても、Qiskit のコードを実行できます。\n", "\n", "**注意** ローカル環境でこのノートブックを実行している場合 (つまりBraket コンソールから実行していない場合)、Braket デバイスにアクセスするために、最初に AWS アカウントが適切に構成されていることを確認する必要があります。[こちらのチュートリアル](https://aws.amazon.com/blogs/quantum-computing/setting-up-your-local-development-environment-in-amazon-braket/)で、その手順をご確認ください。" ] }, { "cell_type": "markdown", "id": "f4f2f12a-d87a-4f4d-b018-f465b383e19a", "metadata": {}, "source": [ "## Qiskit から Braket デバイスにアクセスする\n", "\n", "Amazon Braket のバックエンドデバイスはかなり種類が多いため、それぞれのおすすめユースケースを 1 つずつ説明していきます。" ] }, { "cell_type": "markdown", "id": "d3df9002-d332-4d31-abdb-eddf1bb27948", "metadata": {}, "source": [ "### 量子シミュレータ\n", "\n", "まず、ローカルシミュレータから始めましょう。これはローカル環境で動作する量子フル状態ベクトルシミュレータです。ローカル環境とは、この Jupyter ノートブックの実行場所 (例えば、ローカル開発環境や Braket コンソール上のノートブックインスタンスなど) を指します。\n", "\n", "**推奨ユースケース:** 最大 12 量子ビットのノイズなし回路" ] }, { "cell_type": "code", "execution_count": 2, "id": "bcb65696-6018-4bbc-aa56-1cfefa0f80fa", "metadata": { "tags": [] }, "outputs": [], "source": [ "from qiskit_braket_provider import BraketLocalBackend\n", "\n", "local_simulator = BraketLocalBackend()" ] }, { "cell_type": "markdown", "id": "413de274-7c4b-402a-9140-6064d8430264", "metadata": {}, "source": [ "次に、ローカル密度行列シミュレータです。このシミュレータもローカル環境で動作しますが、量子回路に対するノイズの影響をシミュレートできます。密度行列は状態ベクトルの 2 倍の大きさなので、効果的にシミュレートできる量子ビット数は、ローカル状態ベクトルシミュレータの半分になります。\n", "\n", "**推奨ユースケース :** 最大 6 量子ビットのノイズあり回路" ] }, { "cell_type": "code", "execution_count": 3, "id": "c16bb05a-925e-4706-ad11-0580181173d9", "metadata": { "tags": [] }, "outputs": [], "source": [ "local_dm_simulator = BraketLocalBackend(name='braket_dm')" ] }, { "cell_type": "markdown", "id": "8b8d88de-8bee-4298-8cc4-89f7b3280ff8", "metadata": {}, "source": [ "Braket オンデマンドシミュレータは、AWS のコンピューティングリソース上で動作し、ローカルシミュレータの機能に加え、いくつかの拡張機能を備えています。以下のコードで、利用可能な Braket のシミュレータをすべてリストアップすることができます。" ] }, { "cell_type": "code", "execution_count": 4, "id": "a0d738da-fb1a-4430-926e-c41608b5b923", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "[BraketBackend[SV1], BraketBackend[TN1], BraketBackend[dm1]]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qiskit_braket_provider import AWSBraketProvider\n", "\n", "provider = AWSBraketProvider()\n", "\n", "provider.backends(statuses=[\"ONLINE\"], types=[\"SIMULATOR\"])" ] }, { "cell_type": "markdown", "id": "4fd3c5ba-7c3f-42d5-bad4-8688df3f456a", "metadata": {}, "source": [ "オンデマンドシミュレータの 1 つめは SV1 です。これはフル状態ベクトルシミュレータで、ローカルシミュレータよりも大規模な回路のシミュレーションが可能です。また、タスクをバッチ処理して並列実行する機能とともに、変分量子アルゴリズムの adjoint 勾配計算などの応用テクニックも使用できます。\n", "\n", "**推奨ユースケース :** 最大 34 量子ビットのノイズなし変分アルゴリズム" ] }, { "cell_type": "code", "execution_count": 5, "id": "d72c0fee-c643-46e6-b536-922b3d5e1b63", "metadata": { "tags": [] }, "outputs": [], "source": [ "aws_sv1 = provider.get_backend(\"SV1\")" ] }, { "cell_type": "markdown", "id": "022f2518-cbb8-4679-8175-b0347fe41955", "metadata": {}, "source": [ "2 つめのオンデマンドシミュレータは DM1 です。これは密度行列シミュレータで、SV1 と同様に、より多くの量子ビットをシミュレートでき、バッチ実行も可能です。\n", "\n", "**推奨ユースケース :** 最大 17 量子ビットのノイズあり変分アルゴリズム" ] }, { "cell_type": "code", "execution_count": 6, "id": "a1d6a663-7717-40ca-9bd1-4ea0e2591757", "metadata": { "tags": [] }, "outputs": [], "source": [ "aws_dm1 = provider.get_backend(\"dm1\")" ] }, { "cell_type": "markdown", "id": "0b8e5316-46ea-4c81-b855-78d8d2784bc7", "metadata": {}, "source": [ "最後のオンデマンドシミュレータは TN1 です。これはテンソルネットワークシミュレータで、回路内の各ゲートをテンソルとして表現します。TN1 は、局所的なゲートやその他の特殊な構造を持つ回路では、より多くの量子ビットをシミュレートできますが、長距離のゲートや all-to-all のゲート構造を持つ回路に対しては、SV1 や DM1 よりも遅くなるのが普通です。\n", "\n", "**推奨ユースケース :** 局所的な接続性を持ち、最大 50 量子ビットのノイズなし回路" ] }, { "cell_type": "markdown", "id": "3888f97e-fb68-428c-95ba-bff9b1e9fecc", "metadata": {}, "source": [ "**注意:** 各 AWS リソース (ファイル、CPU、QPUなど) は特定のリージョンにのみ存在し、そのリージョンからしかアクセスできない場合があります。例えば、TN1 は `eu-west-2`、 `us-east-1`、 `us-west-2` リージョンでのみ利用可能です。\n", "\n", "マネージドノートブックで実行している場合に AWS リージョンを変更するには、AWS コンソールの右上から新しいリージョンを選択し、Braket コンソールからノートブックを再起動または作成する必要があります。\n", "\n", "ローカル開発環境で実行している場合に AWS リージョンを変更するには、次のコードスニペットを実行します。\n", "```\n", "import os\n", "os.environ[\"AWS_REGION\"] = \"your-desired-region\"\n", "```" ] }, { "cell_type": "code", "execution_count": 9, "id": "c3727ffa-36ea-4d8f-926a-5a7bed46cd57", "metadata": { "tags": [] }, "outputs": [], "source": [ "# TN1 にアクセスできるリージョンの 1 つに切り替えた場合は、次のコードのコメントを自由に解除できます。\n", "# aws_tn1 = provider.get_backend(\"TN1\")" ] }, { "cell_type": "markdown", "id": "37f15848-db35-4a3b-8efb-2790f25f9708", "metadata": {}, "source": [ "### 量子処理ユニット (QPU)\n", "\n", "Amazon Braket では、多くのサードパーティ製量子ハードウェアデバイスへのアクセスも可能です。以下のコードは、現在オンラインの、サポートされている QPU を表示します。" ] }, { "cell_type": "code", "execution_count": 10, "id": "891dbaac-f94f-41f9-947d-bed68342aca9", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "[BraketBackend[Aspen-M-3], BraketBackend[Harmony]]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "provider.backends(statuses=[\"ONLINE\"], types=[\"QPU\"])" ] }, { "cell_type": "markdown", "id": "906cccb3-4893-494a-8718-6b4b4a66621d", "metadata": {}, "source": [ "各量子コンピュータの詳細については、Braket ホームページの [Providers Overview](https://aws.amazon.com/braket/quantum-computers/)、または Braket コンソールの左側にある Devices タブから確認できます。\n", "現在、Qiskit-Braket プロバイダでサポートされているのは、ゲートベースのQPU (IonQ, OQC, Rigetti) のみです。" ] }, { "cell_type": "markdown", "id": "e3af4dfd-d1ba-44aa-a913-18da11b3e520", "metadata": {}, "source": [ "## Braket デバイス上で回路を実行する\n", "\n", "Qiskit-Braket プロバイダで利用可能な量子デバイスについて説明したので、実際に使ってみましょう!今回の例では、Rigetti デバイスで 3 量子 GHZ 状態を作成しますが、以下のコメントアウトされたデバイスから自由に別の QPU を選択できます。" ] }, { "cell_type": "code", "execution_count": 11, "id": "7b870ef3-f2b8-47d4-b571-82ca22925fec", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BraketBackend[Aspen-M-3]\n" ] } ], "source": [ "qpu_backend = provider.get_backend(\"Aspen-M-3\")\n", "# qpu_backend = provider.get_backend(\"Lucy\")\n", "# qpu_backend = provider.get_backend(\"IonQ Device\")\n", "\n", "print(qpu_backend)" ] }, { "cell_type": "code", "execution_count": 12, "id": "dfa16813-80d8-407c-ac6d-ce7bb1982e17", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
┌───┐ \n", "q_0: ┤ H ├──■────■──\n", " └───┘┌─┴─┐ │ \n", "q_1: ─────┤ X ├──┼──\n", " └───┘┌─┴─┐\n", "q_2: ──────────┤ X ├\n", " └───┘" ], "text/plain": [ " ┌───┐ \n", "q_0: ┤ H ├──■────■──\n", " └───┘┌─┴─┐ │ \n", "q_1: ─────┤ X ├──┼──\n", " └───┘┌─┴─┐\n", "q_2: ──────────┤ X ├\n", " └───┘" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qiskit import QuantumCircuit\n", "\n", "circuit = QuantumCircuit(3)\n", "circuit.h(0)\n", "circuit.cx(0, 1)\n", "circuit.cx(0, 2)\n", "circuit.draw()" ] }, { "cell_type": "code", "execution_count": 13, "id": "e6237c66-f833-4554-8542-385c92500ace", "metadata": { "tags": [] }, "outputs": [], "source": [ "# run circuit\n", "qpu_task = qpu_backend.run(circuit, shots=10)" ] }, { "cell_type": "markdown", "id": "b9bc9a23-a786-4fbd-8d90-d97a6e1ef972", "metadata": {}, "source": [ "実行したタスクには、それぞれ固有の ARN(Amazon Resource Name)が割り当てられ、これを保存しておくことで、タスク実行後にノートブックを閉じても、タスクのデータを取得することができます。" ] }, { "cell_type": "code", "execution_count": 14, "id": "c0952b4e-0d8c-4f74-859b-50ad53065854", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'arn:aws:braket:us-west-1:700863243650:quantum-task/1f41ab60-ed25-4352-8d2d-28b6772d94ee'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "task_id = qpu_task.job_id()\n", "task_id" ] }, { "cell_type": "markdown", "id": "24514bc7-06d1-4a7a-9a20-af1b414fb388", "metadata": {}, "source": [ "**注意 :** Amazon Braket で「タスク (task)」と呼ばれるものを、Qiskit は「ジョブ (job)」という名称で使用しています。`.job_id()` を呼び出すことで、タスクの ARN にアクセスできるのはこのためです。\n", "\n", "一方で、Braket には「ハイブリッドジョブ (Hybrid Jobs)」と呼ばれる別の機能があります。この機能は今回のノートブックの範囲を超えていますが、[開発者ガイド](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html)で読むことができます。" ] }, { "cell_type": "code", "execution_count": 15, "id": "b5a183ef-c490-4771-a52b-9f31920115ff", "metadata": { "tags": [] }, "outputs": [], "source": [ "# タスクデータの取得\n", "retrieved_task = qpu_backend.retrieve_job(job_id=task_id)" ] }, { "cell_type": "markdown", "id": "5ba5ad23-cb76-4be4-99f4-c8c90b262470", "metadata": {}, "source": [ "その後、タスクが終了したかどうかステータスで確認できます。" ] }, { "cell_type": "code", "execution_count": 22, "id": "e43a566b-3d67-47d9-bf10-273c02bd569a", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "