├── .gitignore ├── NOTICE ├── workshop ├── circuit.png ├── maxcut_plot.png ├── pennylane │ ├── grouping.png │ ├── params_30.npy │ ├── qchem │ │ ├── h2.xyz │ │ ├── h2_0.30.xyz │ │ ├── h2_0.50.xyz │ │ ├── h2_0.70.xyz │ │ ├── h2_0.90.xyz │ │ ├── h2_1.10.xyz │ │ ├── h2_1.30.xyz │ │ ├── h2_1.50.xyz │ │ ├── h2_1.70.xyz │ │ ├── h2_1.90.xyz │ │ └── h2_2.10.xyz │ └── 3_Quantum_chemistry_with_VQE.ipynb ├── hybrid_jobs │ ├── 0_Creating_your_first_Hybrid_Job │ │ ├── console_figures │ │ │ ├── 1-create.png │ │ │ ├── 2-algorithm.png │ │ │ ├── 3-container.png │ │ │ └── 4-execution.png │ │ ├── algorithm_script.py │ │ ├── algorithm_script_parametrized_circuit.py │ │ └── Creating_your_first_Hybrid_Job.ipynb │ ├── 4_Embedded_simulators_in_Braket_Jobs │ │ ├── qaoa │ │ │ ├── utils.py │ │ │ └── qaoa_algorithm.py │ │ └── Embedded_simulators_in_Braket_Jobs.ipynb │ └── 2_Using_PennyLane_with_Braket_Jobs │ │ └── qaoa │ │ ├── qaoa_utils.py │ │ └── qaoa_algorithm_script.py ├── 0_Getting_started-workshop.ipynb ├── 4_Cost_tracker.ipynb └── qiskit │ └── 0_Getting_Started.ipynb ├── CODE_OF_CONDUCT.md ├── README.md ├── CONTRIBUTING.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints/ 2 | model.tar.gz 3 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /workshop/circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/circuit.png -------------------------------------------------------------------------------- /workshop/maxcut_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/maxcut_plot.png -------------------------------------------------------------------------------- /workshop/pennylane/grouping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/pennylane/grouping.png -------------------------------------------------------------------------------- /workshop/pennylane/params_30.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/pennylane/params_30.npy -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.35000 4 | H 0.00000 0.00000 0.35000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_0.30.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.1500 4 | H 0.00000 0.00000 0.1500 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_0.50.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.25000 4 | H 0.00000 0.00000 0.25000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_0.70.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.35000 4 | H 0.00000 0.00000 0.35000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_0.90.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.45000 4 | H 0.00000 0.00000 0.45000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_1.10.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.55000 4 | H 0.00000 0.00000 0.55000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_1.30.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.65000 4 | H 0.00000 0.00000 0.65000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_1.50.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.75000 4 | H 0.00000 0.00000 0.75000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_1.70.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.85000 4 | H 0.00000 0.00000 0.85000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_1.90.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -0.95000 4 | H 0.00000 0.00000 0.95000 5 | -------------------------------------------------------------------------------- /workshop/pennylane/qchem/h2_2.10.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | in Angstrom 3 | H 0.00000 0.00000 -1.0500 4 | H 0.00000 0.00000 1.0500 5 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/1-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/1-create.png -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/2-algorithm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/2-algorithm.png -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/3-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/3-container.png -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/4-execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-braket-examples-jp/HEAD/workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/console_figures/4-execution.png -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Amazon Braket Examples (Japanese) 2 | 3 | Amazon Braket を使って量子コンピューティングを試すためのチュートリアルです。 4 | Braket Tutorials GitHub [[aws/amazon-braket-examples](https://github.com/aws/amazon-braket-examples)] で公開されているノートブックの一部を日本語訳したり、オリジナルコンテンツを置いています。 5 | [Amazon Braket ノートブックインスタンス](https://docs.aws.amazon.com/ja_jp/braket/latest/developerguide/braket-get-started-create-notebook.html) 上にリポジトリをクローンすれば、実際に Jupyter Notebook を実行して試すことができます。 6 | 7 | ## Security 8 | 9 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 10 | 11 | ## License 12 | 13 | This project is licensed under the Apache-2.0 License. 14 | 15 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/4_Embedded_simulators_in_Braket_Jobs/qaoa/utils.py: -------------------------------------------------------------------------------- 1 | import pennylane as qml 2 | import os 3 | 4 | def get_device(n_wires): 5 | device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"] 6 | device_prefix = device_string.split(":")[0] 7 | 8 | if device_prefix=="local": 9 | prefix, device_name = device_string.split("/") 10 | device = qml.device(device_name, 11 | wires=n_wires, 12 | custom_decomps={"MultiRZ": qml.MultiRZ.compute_decomposition}) 13 | print("Using local simulator: ", device.name) 14 | else: 15 | device = qml.device('braket.aws.qubit', 16 | device_arn=device_string, 17 | s3_destination_folder=None, 18 | wires=n_wires, 19 | parallel=True, 20 | max_parallel=30) 21 | print("Using AWS managed device: ", device.name) 22 | 23 | return device -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/algorithm_script.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). You 4 | # may not use this file except in compliance with the License. A copy of 5 | # the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | # ANY KIND, either express or implied. See the License for the specific 12 | # language governing permissions and limitations under the License. 13 | 14 | import os 15 | 16 | import numpy as np 17 | from braket.aws import AwsDevice 18 | from braket.circuits import Circuit 19 | from braket.jobs import save_job_result 20 | from braket.jobs.metrics import log_metric 21 | from braket.tracking import Tracker 22 | 23 | cost_tracker = Tracker().start() 24 | 25 | print("Test job started!!!!!") 26 | 27 | # Use the device declared in the creation script 28 | device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"]) 29 | 30 | counts_list = [] 31 | angle_list = [] 32 | for i in range(5): 33 | angle = np.pi * np.random.randn() 34 | random_circuit = Circuit().rx(0, angle) 35 | 36 | task = device.run(random_circuit, shots=100) 37 | counts = task.result().measurement_counts 38 | 39 | angle_list.append(angle) 40 | counts_list.append(counts) 41 | print(counts) 42 | 43 | braket_tasks_cost = float(cost_tracker.simulator_tasks_cost() + cost_tracker.qpu_tasks_cost()) 44 | log_metric(metric_name="braket_tasks_cost", value=braket_tasks_cost, iteration_number=i) 45 | 46 | 47 | save_job_result( 48 | { 49 | "counts": counts_list, 50 | "angles": angle_list, 51 | "task summary": cost_tracker.quantum_tasks_statistics(), 52 | "estimated cost": braket_tasks_cost, 53 | } 54 | ) 55 | 56 | print("Test job completed!!!!!") 57 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/algorithm_script_parametrized_circuit.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). You 4 | # may not use this file except in compliance with the License. A copy of 5 | # the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | # ANY KIND, either express or implied. See the License for the specific 12 | # language governing permissions and limitations under the License. 13 | 14 | import os 15 | 16 | import numpy as np 17 | from braket.aws import AwsDevice 18 | from braket.circuits import Circuit, FreeParameter 19 | from braket.jobs import save_job_result 20 | from braket.jobs.metrics import log_metric 21 | from braket.tracking import Tracker 22 | 23 | cost_tracker = Tracker().start() 24 | 25 | print("Test job started!!!!!") 26 | 27 | # Use the device declared in the creation script 28 | device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"]) 29 | 30 | angle = FreeParameter("angle") 31 | parametrized_circuit = Circuit().rx(0, angle) 32 | 33 | counts_list = [] 34 | angle_list = [] 35 | for i in range(5): 36 | angle_value = np.pi * np.random.randn() 37 | 38 | task = device.run(parametrized_circuit, shots=100, inputs={"angle": angle_value}) 39 | counts = task.result().measurement_counts 40 | 41 | angle_list.append(angle_value) 42 | counts_list.append(counts) 43 | print(counts) 44 | 45 | braket_tasks_cost = float(cost_tracker.simulator_tasks_cost() + cost_tracker.qpu_tasks_cost()) 46 | log_metric(metric_name="braket_tasks_cost", value=braket_tasks_cost, iteration_number=i) 47 | 48 | 49 | save_job_result( 50 | { 51 | "counts": counts_list, 52 | "angles": angle_list, 53 | "task summary": cost_tracker.quantum_tasks_statistics(), 54 | "estimated cost": braket_tasks_cost, 55 | } 56 | ) 57 | 58 | print("Test job completed!!!!!") 59 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/4_Embedded_simulators_in_Braket_Jobs/qaoa/qaoa_algorithm.py: -------------------------------------------------------------------------------- 1 | import networkx as nx 2 | import os 3 | import json 4 | 5 | from braket.devices import LocalSimulator 6 | from braket.jobs import save_job_result 7 | from braket.jobs.metrics import log_metric 8 | 9 | import pennylane as qml 10 | from pennylane import numpy as np 11 | 12 | from qaoa.utils import get_device 13 | 14 | 15 | def main(): 16 | ########## Read environment variables ########## 17 | hp_file = os.environ["AMZN_BRAKET_HP_FILE"] 18 | 19 | 20 | ########## Hyperparameters ########## 21 | with open(hp_file, "r") as f: 22 | hyperparams = json.load(f) 23 | print("hyperparams: ", hyperparams) 24 | 25 | # problem-setup hyperparams 26 | n_nodes = int(hyperparams["n_nodes"]) 27 | n_edges = float(hyperparams["n_edges"]) 28 | n_layers = int(hyperparams["n_layers"]) 29 | 30 | # training hyperparams 31 | seed = int(hyperparams["seed"]) 32 | iterations = int(hyperparams["iterations"]) 33 | stepsize = float(hyperparams["stepsize"]) 34 | diff_method = hyperparams["diff_method"] 35 | 36 | ########## Device ########## 37 | device = get_device(n_nodes) 38 | 39 | 40 | ########## Set up graph ########## 41 | g = nx.gnm_random_graph(n_nodes, n_edges, seed=seed) 42 | positions = nx.spring_layout(g, seed=seed) 43 | 44 | cost_h, mixer_h = qml.qaoa.max_clique(g, constrained=False) 45 | print('number of observables: ', len(cost_h._ops)) 46 | 47 | def qaoa_layer(gamma, alpha): 48 | qml.qaoa.cost_layer(gamma, cost_h) 49 | qml.qaoa.mixer_layer(alpha, mixer_h) 50 | 51 | def circuit(params): 52 | for i in range(n_nodes): 53 | qml.Hadamard(wires=i) 54 | qml.layer(qaoa_layer, n_layers, params[0], params[1]) 55 | 56 | @qml.qnode(device, diff_method=diff_method) 57 | def cost_function(params): 58 | circuit(params) 59 | return qml.expval(cost_h) 60 | 61 | 62 | ########## Optimization ########### 63 | print("start optimizing...") 64 | np.random.seed(seed) 65 | params = np.random.uniform(size=[2, n_layers]) 66 | 67 | opt = qml.AdamOptimizer(stepsize=stepsize) 68 | 69 | for i in range(iterations): 70 | params, cost_before = opt.step_and_cost(cost_function, params) 71 | 72 | # Log the loss before the update step as a metric 73 | log_metric( 74 | metric_name="Cost", 75 | value=cost_before, 76 | iteration_number=i, 77 | ) 78 | 79 | 80 | final_cost = float(cost_function(params)) 81 | log_metric( 82 | metric_name="Cost", 83 | value=final_cost, 84 | iteration_number=iterations, 85 | ) 86 | 87 | save_job_result({"params": params.tolist(), "cost": final_cost}) 88 | 89 | 90 | if __name__ == "__main__": 91 | try: 92 | main() 93 | print("Training Successful!!") 94 | except BaseException as e: 95 | print(e) 96 | print("Training Fails...") 97 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /workshop/0_Getting_started-workshop.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Amazon Braket 入門" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "
\n", 15 | "このノートブックは、Amazon Braket のスタート時にクローンされるノートブック\n", 16 | "Braket examples/getting_started/0_Getting_started.ipynb\n", 17 | "に日本語訳と編集を加えたものです。\n", 18 | "
" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "このhello-worldチュートリアルでは、2つのキュービット間で最大限に絡み合ったベル状態を準備します。 次に、ローカルシミュレータで回路を実行し、結果を取得します。" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "# general imports\n", 35 | "import matplotlib.pyplot as plt\n", 36 | "%matplotlib inline\n", 37 | "\n", 38 | "# AWS imports: Import Braket SDK modules\n", 39 | "from braket.circuits import Circuit\n", 40 | "from braket.devices import LocalSimulator" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## 1. Local Simulator で回路を構築する\n", 48 | "\n", 49 | "2つの量子ビットで「ベル状態」を構築しましょう。 `Circuit()` を呼び出すことにより、空の回路を作成し、回路にゲートを追加するだけです。" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "# build a Bell state with two qubits. Here 'cnot(control=0, target=1)' can be simplified as 'cnot(0,1)'\n", 59 | "bell = Circuit().h(0).cnot(control=0, target=1)" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "print(bell)" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "### 回路をローカルシミュレータに送信し、結果を取得します\n", 76 | "\n", 77 | "ここでは、回路をローカルシミュレータに送信して、結果を取得します。" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "# set up device\n", 87 | "device = LocalSimulator()\n", 88 | "\n", 89 | "# run circuit\n", 90 | "result = device.run(bell, shots=10).result()\n", 91 | "# get measurement shots\n", 92 | "counts = result.measurement_counts\n", 93 | "# print counts\n", 94 | "print(counts)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "# plot using Counter\n", 104 | "plt.bar(counts.keys(), counts.values());\n", 105 | "plt.xlabel('bitstrings');\n", 106 | "plt.ylabel('counts');" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "## [演習] shot 数を増やして 量子計算の挙動の違いを確認する\n", 114 | "\n", 115 | "`result = device.run(bell, shots=10).result()`\n", 116 | "shot の数 を 10 -> 100 -> 1000 -> と増やしてみてください。\n", 117 | "(Local Simulator で shot 数を増やしても、shot 数に対して課金される料金に変化はありません)\n", 118 | "\n", 119 | "* shot 数 100,000 以上になると、計算時間が急に増えてきますので、ご注意ください。目安の shot 数は、最大 10,000,000程度まで" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": null, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "%%time\n", 129 | "# run circuit\n", 130 | "result = device.run(bell, shots=10).result()\n", 131 | "# get measurement shots\n", 132 | "counts = result.measurement_probabilities\n", 133 | "# print counts\n", 134 | "print(counts)\n", 135 | "\n", 136 | "# plot using Counter\n", 137 | "plt.bar(counts.keys(), counts.values());\n", 138 | "plt.xlabel('bitstrings');\n", 139 | "plt.ylabel('probabilities');" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "shot の数を10, 100, 1000と増やしていくと、|00>状態と|11>状態の観測確率がほぼ等しく50%に近づいていくことがわかりましたか?\n", 147 | "\n", 148 | "このように、統計誤差を無くすために(理想的な計算をするために)どの程度のショット数が必要かを見積もることができます。" 149 | ] 150 | } 151 | ], 152 | "metadata": { 153 | "kernelspec": { 154 | "display_name": "conda_braket", 155 | "language": "python", 156 | "name": "conda_braket" 157 | }, 158 | "language_info": { 159 | "codemirror_mode": { 160 | "name": "ipython", 161 | "version": 3 162 | }, 163 | "file_extension": ".py", 164 | "mimetype": "text/x-python", 165 | "name": "python", 166 | "nbconvert_exporter": "python", 167 | "pygments_lexer": "ipython3", 168 | "version": "3.7.13" 169 | } 170 | }, 171 | "nbformat": 4, 172 | "nbformat_minor": 4 173 | } 174 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/2_Using_PennyLane_with_Braket_Jobs/qaoa/qaoa_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). You 4 | # may not use this file except in compliance with the License. A copy of 5 | # the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | # ANY KIND, either express or implied. See the License for the specific 12 | # language governing permissions and limitations under the License. 13 | 14 | from abc import ABC, abstractmethod 15 | 16 | 17 | class QAOAInterface(ABC): 18 | @classmethod 19 | @abstractmethod 20 | def initialize_params(cls, np_array): 21 | """Initialize the parameters to the appropriate format for the autodiff library. 22 | Args: 23 | np_array (np.ndarray): Input parameters in Numpy array format. 24 | Returns: 25 | array_like: Parameter format needed for the autodiff library. 26 | """ 27 | pass 28 | 29 | @classmethod 30 | @abstractmethod 31 | def get_sgd_optimizer(cls, stepsize, params): 32 | """Returns the gradient descent optimizer to use, based on the ML framework. 33 | Args: 34 | stepsize (float): Step size for the gradient descent optimizer. 35 | params (array_like): Input parameters, required for the PyTorch optimizer. 36 | Returns: 37 | callable: Gradient descent optimizer for the ML framework. 38 | """ 39 | pass 40 | 41 | @classmethod 42 | @abstractmethod 43 | def convert_params_to_numpy(cls, params): 44 | """Convert params to base Numpy arrays. 45 | Args: 46 | params (array_like): A set of parameters. 47 | Returns: 48 | np.ndarray: The parameters converted to a Numpy array. 49 | """ 50 | pass 51 | 52 | @classmethod 53 | @abstractmethod 54 | def get_cost_and_step(cls, cost_function, params, optimizer): 55 | """Evaluate the cost function, then take a step. 56 | Args: 57 | cost_function (callable): The cost function. 58 | params (array_like): The current set of parameters. 59 | optimizer (callable): The optimizer. 60 | Returns: 61 | tuple(array_like, float): The updated set of parameters, and the cost function evaluated 62 | before the update. 63 | """ 64 | pass 65 | 66 | @staticmethod 67 | def get_interface(interface): 68 | """Get the appropriate interface to use based on the string input. 69 | Args: 70 | interface (string): A string specifying the interface to use. 71 | Must be "autograd", "tf", or "torch". 72 | Returns: 73 | QAOAInterface: An interface matching the specified string. 74 | """ 75 | if interface == "autograd": 76 | return AutogradInterface() 77 | elif interface == "tf": 78 | return TensorFlowInterface() 79 | elif interface == "torch": 80 | return PyTorchInterface() 81 | else: 82 | raise ValueError(f"Interface {interface} is invalid.") 83 | 84 | 85 | class AutogradInterface(QAOAInterface): 86 | # Import only in __init__ so we don't import a library that doesn't exist in the container. 87 | def __init__(self): 88 | global qml 89 | qml = __import__("pennylane", globals(), locals()) 90 | # Equiv to: import pennylane as qml 91 | 92 | @classmethod 93 | def initialize_params(cls, np_array): 94 | return qml.numpy.array(np_array, requires_grad=True) 95 | 96 | @classmethod 97 | def get_sgd_optimizer(cls, stepsize, params): 98 | return qml.GradientDescentOptimizer(stepsize=stepsize) 99 | 100 | @classmethod 101 | def convert_params_to_numpy(cls, params): 102 | return params.numpy() 103 | 104 | @classmethod 105 | def get_cost_and_step(cls, cost_function, params, optimizer): 106 | params, cost_before = optimizer.step_and_cost(cost_function, params) 107 | return params, float(cost_before) 108 | 109 | 110 | class TensorFlowInterface(QAOAInterface): 111 | # Import only in __init__ so we don't import a library that doesn't exist in the container. 112 | def __init__(self): 113 | global tf 114 | tf = __import__("tensorflow", globals(), locals()) 115 | # Equiv to: import tensorflow as tf 116 | 117 | @classmethod 118 | def initialize_params(cls, np_array): 119 | return tf.Variable(np_array, dtype=tf.float64) 120 | 121 | @classmethod 122 | def get_sgd_optimizer(cls, stepsize, params): 123 | return tf.keras.optimizers.legacy.SGD(learning_rate=stepsize) 124 | 125 | @classmethod 126 | def convert_params_to_numpy(cls, params): 127 | return params.numpy() 128 | 129 | @classmethod 130 | def get_cost_and_step(cls, cost_function, params, optimizer): 131 | def tf_cost(): 132 | global _cached_cost_before 133 | _cached_cost_before = cost_function(params) 134 | return _cached_cost_before 135 | 136 | optimizer.minimize(tf_cost, params) 137 | cost_before = _cached_cost_before 138 | 139 | # Alternative: 140 | # with tf.GradientTape() as tape: 141 | # cost_before = cost_function(params) 142 | # 143 | # gradients = tape.gradient(cost_before, params) 144 | # optimizer.apply_gradients(((gradients, params),)) 145 | 146 | return params, float(cost_before) 147 | 148 | 149 | class PyTorchInterface(QAOAInterface): 150 | # Import only in __init__ so we don't import a library that doesn't exist in the container. 151 | def __init__(self): 152 | global torch 153 | torch = __import__("torch", globals(), locals()) 154 | # Equiv to: import torch 155 | 156 | @classmethod 157 | def initialize_params(cls, np_array): 158 | return torch.tensor(np_array, requires_grad=True) 159 | 160 | @classmethod 161 | def get_sgd_optimizer(cls, stepsize, params): 162 | return torch.optim.SGD([params], lr=stepsize) 163 | 164 | @classmethod 165 | def convert_params_to_numpy(cls, params): 166 | return params.detach().numpy() 167 | 168 | @classmethod 169 | def get_cost_and_step(cls, cost_function, params, optimizer): 170 | optimizer.zero_grad() 171 | cost_before = cost_function(params) 172 | cost_before.backward() 173 | optimizer.step() 174 | return params, float(cost_before) 175 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/2_Using_PennyLane_with_Braket_Jobs/qaoa/qaoa_algorithm_script.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). You 4 | # may not use this file except in compliance with the License. A copy of 5 | # the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | # ANY KIND, either express or implied. See the License for the specific 12 | # language governing permissions and limitations under the License. 13 | 14 | import json 15 | import os 16 | import time 17 | 18 | import networkx as nx 19 | import numpy as np 20 | import pennylane as qml 21 | from braket.jobs import load_job_checkpoint, save_job_checkpoint, save_job_result 22 | from braket.jobs.metrics import log_metric 23 | from braket.tracking import Tracker 24 | from matplotlib import pyplot as plt 25 | 26 | import qaoa.qaoa_utils as qaoa_utils # isort:skip 27 | 28 | 29 | def init_pl_device(device_arn, num_nodes, shots, max_parallel): 30 | return qml.device( 31 | "braket.aws.qubit", 32 | device_arn=device_arn, 33 | wires=num_nodes, 34 | shots=shots, 35 | # Set s3_destination_folder=None to output task results to a default folder 36 | s3_destination_folder=None, 37 | parallel=True, 38 | max_parallel=max_parallel, 39 | # poll_timeout_seconds=30, 40 | ) 41 | 42 | 43 | def main(): 44 | cost_tracker = Tracker().start() 45 | 46 | # lets see the env variables 47 | # print statements can be viewed in cloudwatch 48 | print(os.environ) 49 | 50 | input_dir = os.environ["AMZN_BRAKET_INPUT_DIR"] 51 | output_dir = os.environ["AMZN_BRAKET_JOB_RESULTS_DIR"] 52 | job_name = os.environ["AMZN_BRAKET_JOB_NAME"] # noqa 53 | checkpoint_dir = os.environ["AMZN_BRAKET_CHECKPOINT_DIR"] # noqa 54 | hp_file = os.environ["AMZN_BRAKET_HP_FILE"] 55 | device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"] 56 | 57 | # Read the hyperparameters 58 | with open(hp_file) as f: 59 | hyperparams = json.load(f) 60 | print(hyperparams) 61 | 62 | p = int(hyperparams["p"]) 63 | seed = int(hyperparams["seed"]) 64 | max_parallel = int(hyperparams["max_parallel"]) 65 | num_iterations = int(hyperparams["num_iterations"]) 66 | stepsize = float(hyperparams["stepsize"]) 67 | shots = int(hyperparams["shots"]) 68 | pl_interface = hyperparams["interface"] 69 | if "copy_checkpoints_from_job" in hyperparams: 70 | copy_checkpoints_from_job = hyperparams["copy_checkpoints_from_job"].split("/", 2)[-1] 71 | else: 72 | copy_checkpoints_from_job = None 73 | 74 | interface = qaoa_utils.QAOAInterface.get_interface(pl_interface) 75 | 76 | # Read graph from input file 77 | g = nx.read_adjlist(f"{input_dir}/input-graph/input-data.adjlist", nodetype=int) 78 | num_nodes = len(g.nodes) 79 | 80 | # Draw graph to an output file 81 | positions = nx.spring_layout(g, seed=seed) 82 | nx.draw(g, with_labels=True, pos=positions, node_size=600) 83 | plt.savefig(f"{output_dir}/graph.png") 84 | 85 | # Set up the QAOA problem 86 | cost_h, mixer_h = qml.qaoa.maxcut(g) 87 | 88 | def qaoa_layer(gamma, alpha): 89 | qml.qaoa.cost_layer(gamma, cost_h) 90 | qml.qaoa.mixer_layer(alpha, mixer_h) 91 | 92 | def circuit(params, **kwargs): 93 | for i in range(num_nodes): 94 | qml.Hadamard(wires=i) 95 | qml.layer(qaoa_layer, p, params[0], params[1]) 96 | 97 | dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) 98 | 99 | np.random.seed(seed) 100 | 101 | @qml.qnode(dev, interface=pl_interface) 102 | def cost_function(params, **kwargs): 103 | circuit(params, **kwargs) 104 | return qml.expval(cost_h) 105 | 106 | # Load checkpoint if it exists 107 | if copy_checkpoints_from_job: 108 | checkpoint_1 = load_job_checkpoint( 109 | copy_checkpoints_from_job, 110 | checkpoint_file_suffix="checkpoint-1", 111 | ) 112 | start_iteration = checkpoint_1["iteration"] 113 | params = interface.initialize_params(np.array(checkpoint_1["params"])) 114 | print("Checkpoint loaded") 115 | else: 116 | start_iteration = 0 117 | params = interface.initialize_params(0.01 * np.random.uniform(size=[2, p])) 118 | 119 | optimizer = interface.get_sgd_optimizer(stepsize, params) 120 | print("Optimization start") 121 | 122 | for iteration in range(start_iteration, num_iterations): 123 | t0 = time.time() 124 | 125 | # Evaluates the cost, then does a gradient step to new params 126 | params, cost_before = interface.get_cost_and_step(cost_function, params, optimizer) 127 | # Convert params to a Numpy array so they're easier to handle for us 128 | np_params = interface.convert_params_to_numpy(params) 129 | 130 | t1 = time.time() 131 | 132 | if iteration == 0: 133 | print("Initial cost:", cost_before) 134 | else: 135 | print(f"Cost at step {iteration}:", cost_before) 136 | 137 | # Track the cost as a metric 138 | timestamp = time.time() 139 | braket_tasks_cost = float( 140 | cost_tracker.simulator_tasks_cost() + cost_tracker.qpu_tasks_cost() 141 | ) 142 | log_metric( 143 | metric_name="braket_tasks_cost", 144 | value=braket_tasks_cost, 145 | iteration_number=iteration, 146 | timestamp=timestamp, 147 | ) 148 | 149 | # Log the loss before the update step as a metric 150 | log_metric( 151 | metric_name="Cost", 152 | value=cost_before, 153 | iteration_number=iteration, 154 | timestamp=timestamp, 155 | ) 156 | 157 | # Save the current params and previous cost to a checkpoint 158 | save_job_checkpoint( 159 | checkpoint_data={ 160 | "iteration": iteration + 1, 161 | "params": np_params.tolist(), 162 | "cost_before": cost_before, 163 | }, 164 | checkpoint_file_suffix="checkpoint-1", 165 | ) 166 | 167 | print(f"Completed iteration {iteration + 1}") 168 | print(f"Time to complete iteration: {t1 - t0} seconds") 169 | 170 | final_cost = float(cost_function(params)) 171 | print(f"Cost at step {num_iterations}:", final_cost) 172 | 173 | # We're done with the job, so save the result. 174 | # This will be returned in job.result() 175 | save_job_result( 176 | { 177 | "params": np_params.tolist(), 178 | "cost": final_cost, 179 | "task summary": cost_tracker.quantum_tasks_statistics(), 180 | "estimated cost": cost_tracker.qpu_tasks_cost() + cost_tracker.simulator_tasks_cost(), 181 | } 182 | ) 183 | 184 | 185 | if __name__ == "__main__": 186 | main() 187 | -------------------------------------------------------------------------------- /workshop/4_Cost_tracker.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "a185a2a9", 6 | "metadata": {}, 7 | "source": [ 8 | "# ニアリアルタイムのコストトラッキングツール : Amazon Braket Cost Tracker" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "ca1cf9d8", 14 | "metadata": {}, 15 | "source": [ 16 | "
\n", 17 | "このノートブックは、Amazon Braket のコスト管理 (原文: Managing the cost of your experiments in Amazon Braket) の一部に編集を加えたものです。\n", 18 | "
" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "id": "64eee798", 24 | "metadata": {}, 25 | "source": [ 26 | "ある量子アルゴリズムが複雑であるため、その実行コストを事前に予測することが難しい場合があります。例えば、QML ハイブリッドアルゴリズムの実行時間は、収束に必要なイテレーション回数に依存します。最近、私たちは Amazon Braket Cost Tracker というツールを発表しました。この Cost Tracker は現在は Braket SDK に組み込まれています。このツールを用いることで、量子ワークロードが取りうる最大コストを、ほぼリアルタイムで見積もることができるようになります。\n", 27 | "\n", 28 | "Braket Cost Tracker の 1 行のコードを追加することで、QPU のタスクやショットにかかるコストや、シミュレーターの利用時間にかかるコストといった、使用する量子リソースごとのコストを把握できるようになります。\n", 29 | "\n", 30 | "このツールを使うには、まず `Tracker()` オブジェクトを初期化し、後はいつも通りにアルゴリズムを定義して実行します。このオブジェクトは、実行されるコンテクスト内のリソースをトラッキングします。トラッキングの範囲は、Notebook 全体にわたることも、変分アルゴリズム内の特定のイテレーションのみに絞ることも可能です。Cost Tracker は、使用状況をトラッキングし、コスト管理ロジックを簡略化するメソッドを提供します。これらの使い方は Braket SDK のドキュメントに記載されています。\n", 31 | "\n", 32 | "Cost Tracker を実際に動かしてみましょう。以下の例では、ベル状態の回路を作成し、SV1 シミュレーター上で実行します。まず Braket SDK をインポートし、ベル状態を定義し、作成された量子タスクを追跡するために `Tracker()` オブジェクトをインスタンス化します。statistics と cost メソッドを呼び出すと、送信されたショット数、完了したタスクとそのステータス、実行時間、請求される実行時間、最大コスト (USD) が返されます。実行時間はシミュレーションごとに異なる場合があります。" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 1, 38 | "id": "981d8d8b", 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "Counter({'00': 54, '11': 46})\n", 46 | "Task statistics: {'arn:aws:braket:::device/quantum-simulator/amazon/sv1': {'shots': 100, 'tasks': {'COMPLETED': 1}, 'execution_duration': datetime.timedelta(microseconds=48000), 'billed_execution_duration': datetime.timedelta(seconds=3)}}\n", 47 | "Estimated cost to run this example: 0.00375 USD\n" 48 | ] 49 | } 50 | ], 51 | "source": [ 52 | "# Import any required modules\n", 53 | "from braket.aws import AwsDevice\n", 54 | "from braket.circuits import Circuit\n", 55 | "from braket.tracking import Tracker\n", 56 | "from braket.annealing import Problem,ProblemType\n", 57 | "\n", 58 | "# Create Bell state and initialize tracking\n", 59 | "circ = Circuit().h(0).cnot(0,1)\n", 60 | "device = AwsDevice(\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\")\n", 61 | "with Tracker() as tracker:\n", 62 | " task = device.run(circ, shots=100).result()\n", 63 | "\n", 64 | "# Your results\n", 65 | "print(task.measurement_counts)\n", 66 | "\n", 67 | "# Print tracker results\n", 68 | "print(f\"Task statistics: {tracker.quantum_tasks_statistics()}\")\n", 69 | "print(f\"Estimated cost to run this example: {tracker.simulator_tasks_cost():.5f} USD\")" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "id": "999bc914", 75 | "metadata": {}, 76 | "source": [ 77 | "このように、実行時間は 0.048 秒ですが、請求される実行時間は 3 秒です。これはシミュレータータスクの最低料金が 3 秒分であるためです。次に、device 変数を Aspen-M-3 QPU に変えて同じ回路を実行してみましょう。Cost Tracker の statistics メソッドを呼び出すと、実行時間の記述がなくなっています。これは、タスクとショットのみが料金計算の要素となるためです。" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "id": "55ea7f99", 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "Counter({'00': 46, '11': 44, '10': 7, '01': 3})\n", 91 | "Task statistics: {'arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3': {'shots': 100, 'tasks': {'COMPLETED': 1}}}\n", 92 | "Estimated cost to run this example: 0.335 USD\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "# Create Bell state and initialize tracking \n", 98 | "circ = Circuit().h(0).cnot(0,1)\n", 99 | "device = AwsDevice(\"arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3\")\n", 100 | "with Tracker() as tracker:\n", 101 | " task = device.run(circ, shots=100).result()\n", 102 | "\n", 103 | "# Your results\n", 104 | "print(task.measurement_counts)\n", 105 | "\n", 106 | "# Print tracker results\n", 107 | "print(f\"Task statistics: {tracker.quantum_tasks_statistics()}\")\n", 108 | "print(f\"Estimated cost to run this example: {tracker.qpu_tasks_cost():.3f} USD\")" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "id": "c5b53209", 114 | "metadata": {}, 115 | "source": [ 116 | "## Cost Tracker を使用してコスト管理ロジックを追加する\n", 117 | "\n", 118 | "Tracker を使用して、実験にコスト管理ロジックを追加することができます。例えば、最大料金を設定し、与えられたワークロードにいくらまでなら支出してもよいか、といったことを決めることができます。以下の例は、Aspen-M-3 上で ベル状態の回路を実行し、総料金が定義された上限 (2.00 USD) を超えたら新しいタスクの実行を停止しています。これによってコストを制限しています。Tracker によると、1 タスク + 100 ショットのコストは 0.34 USD です。ここでは 2 USD を越えるまで問題を繰り返し実行し、その都度コストを表示するロジックを設定しています (結果的に 6 回実行することになります)。これにより、コストを指定した最大料金に近づけながらタスクを複数回実行できるため、実験に柔軟性が生まれます。" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 5, 124 | "id": "35bd6238", 125 | "metadata": {}, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "Estimated cost: 0.34 USD\n", 132 | "Estimated cost: 0.67 USD\n", 133 | "Estimated cost: 1.00 USD\n", 134 | "Estimated cost: 1.34 USD\n", 135 | "Estimated cost: 1.68 USD\n", 136 | "Estimated cost: 2.01 USD\n", 137 | "Task statistics: {'arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3': {'shots': 600, 'tasks': {'COMPLETED': 6}}}\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "# Create Bell state and initialize tracking \n", 143 | "circ = Circuit().h(0).cnot(0,1)\n", 144 | "device = AwsDevice(\"arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3\")\n", 145 | "with Tracker() as tracker:\n", 146 | " while tracker.qpu_tasks_cost() <= 2:\n", 147 | " task = device.run(circ, shots=100).result()\n", 148 | " # Print the cost of each iteration\n", 149 | " print(f\"Estimated cost: {tracker.qpu_tasks_cost():.2f} USD\")\n", 150 | " \n", 151 | "# Print final results\n", 152 | "print(f\"Task statistics: {tracker.quantum_tasks_statistics()}\")" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "id": "ac2802b6", 158 | "metadata": {}, 159 | "source": [ 160 | "ここまでの例では、Tracker は 1 つの量子回路に対して起動・停止していました。しかし、Tracker を 1 つの Notebook にわたって実行したり、Hybrid Jobsの特定のイテレーションに限定して使うこともできます。コストを調べたい箇所で、 `start` メソッドや `stop` メソッドを呼び出すだけで良いのです。" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "id": "0cf21497", 166 | "metadata": {}, 167 | "source": [ 168 | "## まとめ\n", 169 | "このノートブックでは、Braket SDK 上でほぼリアルタイムにコストをトラッキングできる Braket Cost Tracker を紹介しました。新しく登場した Cost Tracker は、既にすべての Braket Notebook サンプルに埋め込まれています。そのためコストの見通しが立てやすくなり、既存のワークロードにも組み込みやすくなりました。今すぐご利用を開始し、その効果を実感してみましょう!" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "d76ffc9b", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "conda_braket", 184 | "language": "python", 185 | "name": "conda_braket" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.10.11" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 5 202 | } 203 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/4_Embedded_simulators_in_Braket_Jobs/Embedded_simulators_in_Braket_Jobs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e4e6801d-93b4-412e-ba51-fb6df7c84827", 6 | "metadata": { 7 | "tags": [] 8 | }, 9 | "source": [ 10 | "# Embedded Simulator in Braket Jobs" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "9413fd8a-ca76-4076-877c-148b20fdba40", 16 | "metadata": {}, 17 | "source": [ 18 | "このノートブックでは、Braket Jobs の Embedded Simulator を紹介します。Embedded Simulator とは、ジョブインスタンス (アルゴリズムスクリプトを実行する計算リソース) 上で動作するローカルシミュレータのことです。一方、SV1, DM1, TN1 などの[オンデマンドシミュレータ](https://docs.aws.amazon.com/braket/latest/developerguide/braket-devices.html#braket-simulator-sv1)は、Amazon Braket によるオンデマンドの専用計算リソース上で量子回路の結果を計算するものです。量子・古典ハイブリッドワークロードは通常、量子回路の実行と変分パラメータの最適化の繰り返しで構成されています。Embedded Simulator を使用することで、全ての計算を同じ環境で行うことができます。これにより、最適化アルゴリズムは、Embedded Simulator が持つさまざまな機能を使うことができます。例えば、PennyLane を介して、サポートされているシミュレータに[随伴法や誤差逆伝播法](https://pennylane.readthedocs.io/en/stable/introduction/interfaces.html#simulation-based-differentiation) などの高度な勾配計算手法を活用することができます。これらの方法は、波動関数の中間状態へのアクセスに依存しており、Amazon Braket のオンデマンドシミュレータや QPU ではサポートされていません。さらに、Jobs の [Bring Your Own Container (BYOC)](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-byoc.html) 機能により、ユーザーはオープンソースシミュレータや独自のシミュレーションツールを使うこともできます。\n", 19 | "\n", 20 | "手動で設定した[Amazon EC2 インスタンス](https://aws.amazon.com/ec2/)や、ユーザーのローカル環境で実行するローカルシミュレータとは異なり、Hybrid Jobs はお客様に代わって計算資源を管理します。ジョブインスタンスは、ジョブの作成時に自動的に起動し、ジョブが終了すると終了するため、お客様は使用したリソースに対してのみ料金を支払います。お客様は複数のジョブを同時に投入することで、ハイパーパラメーターの最適化などの実験を加速させることができます。また、ジョブ作成時に選択するデバイスを変更することで、Embedded Simulator から QPU を含む他の Amazon Braket デバイスに切り替えることもできます。" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "id": "21b02529-8438-4ffa-a6d2-845c96ba2206", 26 | "metadata": {}, 27 | "source": [ 28 | "## Embedded Simulator に用いるデバイスの指定\n", 29 | "\n", 30 | "普通、ジョブを作成する際には、`AwsQuantumJob.create()` の `device` 引数にオンデマンドシミュレータか QPU の ARN (Amazon Resource Name) を指定します。しかし Embedded Simulator を使う際は、代わりに `device` 引数に
\n", 31 | "`device = \"local:/\"`
という形式の文字列を指定します。\n", 32 | "`` と `` は、英数字、`_`、`-`、`.` のみから構成される必要があります。例えば、[Braket-Pennylane プラグイン](https://github.com/aws/amazon-braket-pennylane-plugin-python)を使って Embedded Simulator を使うには、次のように記述します。" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "id": "41775044-2071-4a8a-a36d-b968b11326f7", 39 | "metadata": { 40 | "tags": [] 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "device = \"local:braket/braket.local.qubit\"" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "id": "d3efc94f-8eb2-4079-84bc-194a3045ad7a", 50 | "metadata": {}, 51 | "source": [ 52 | "アルゴリズムスクリプトは、環境変数 `\"AMZN_BRAKET_DEVICE_ARN\"` を通じて、文字列 `device` にアクセスできます。 Braket では、`` と `` にロジックを実行しません。お客様は、アルゴリズムスクリプト内で `` と `` を指定し、任意のシミュレータを作成することができます。このノートでは、Braket-PennyLane プラグインを通してシミュレータを使用します。アルゴリズムスクリプトの一部として、ヘルパー関数 `get_device()` を用意し、`device` 変数をパースして PennyLane `qml.device` をセットアップします。" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 4, 58 | "id": "9a43c79a-41e7-4c15-9e6b-2b812a53c782", 59 | "metadata": { 60 | "tags": [] 61 | }, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "import pennylane as qml\n", 68 | "import os\n", 69 | "\n", 70 | "def get_device(n_wires):\n", 71 | " device_string = os.environ[\"AMZN_BRAKET_DEVICE_ARN\"]\n", 72 | " device_prefix = device_string.split(\":\")[0]\n", 73 | "\n", 74 | " if device_prefix==\"local\":\n", 75 | " prefix, device_name = device_string.split(\"/\")\n", 76 | " device = qml.device(device_name, \n", 77 | " wires=n_wires, \n", 78 | " custom_decomps={\"MultiRZ\": qml.MultiRZ.compute_decomposition})\n", 79 | " print(\"Using local simulator: \", device.name)\n", 80 | " else:\n", 81 | " device = qml.device('braket.aws.qubit', \n", 82 | " device_arn=device_string, \n", 83 | " s3_destination_folder=None,\n", 84 | " wires=n_wires,\n", 85 | " parallel=True,\n", 86 | " max_parallel=30)\n", 87 | " print(\"Using AWS managed device: \", device.name)\n", 88 | " \n", 89 | " return device" 90 | ] 91 | } 92 | ], 93 | "source": [ 94 | "!cat qaoa/utils.py" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "id": "fbefae7f-5210-4ea5-9d69-160c7d2be57e", 100 | "metadata": {}, 101 | "source": [ 102 | "## Embedded Simulator を用いたジョブの実行\n", 103 | "今回の例では、Embedded Simulator 上で Hybrid Jobs を使い、グラフの全結合ノードの最大集合を求める Max-Clique 問題に対して QAOA アルゴリズムを実行します。詳細については、[グラフ最適化ノートブック](https://github.com/aws/amazon-braket-examples/blob/main/examples/pennylane/2_Graph_optimization_with_QAOA/2_Graph_optimization_with_QAOA.ipynb)を参照ください。今回使う QAOA スクリプトは、[qaoa_algorithm.py](https://github.com/aws/amazon-braket-examples/blob/main/examples/hybrid_jobs/4_Embedded_simulators_in_Braket_Jobs/qaoa/qaoa_algorithm.py) で定義されています。このアルゴリズムでは、`n_nodes` や `n_edges` といった Max-Clique 問題の設定に関連するハイパーパラメータと、反復回数やステップ数といった学習そのものに関連するパラメータが必要です。" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 5, 109 | "id": "40828262-df79-462a-877a-0088276f1652", 110 | "metadata": { 111 | "tags": [] 112 | }, 113 | "outputs": [], 114 | "source": [ 115 | "hyperparameters={\n", 116 | " \"n_nodes\": 6, \n", 117 | " \"n_edges\": 8, \n", 118 | " \"n_layers\": 3,\n", 119 | " \"iterations\": 10,\n", 120 | " \"stepsize\": 0.1,\n", 121 | " \"seed\": 42,\n", 122 | " \"diff_method\": \"parameter-shift\",\n", 123 | "}" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "id": "d143b38a-44d3-4213-b3b4-8c03fcbda344", 129 | "metadata": {}, 130 | "source": [ 131 | "アルゴリズムは PennyLane で書かれているため、対応するコンテナを選択する必要があります。PennyLane を含む構成済みのコンテナとして、PyTorch コンテナと TensorFlow コンテナの 2 つがあります。設定済みのコンテナについては [開発者ガイド](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-script-environment.html) を参照ください。それでは、PyTorch コンテナを実行してみましょう。" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 6, 137 | "id": "68ed33f9-0ca2-49c9-bb79-91728752e229", 138 | "metadata": { 139 | "tags": [] 140 | }, 141 | "outputs": [ 142 | { 143 | "name": "stdout", 144 | "output_type": "stream", 145 | "text": [ 146 | "292282985366.dkr.ecr.us-east-1.amazonaws.com/amazon-braket-pytorch-jobs:1.13.1-gpu-py39-cu117-ubuntu20.04\n" 147 | ] 148 | } 149 | ], 150 | "source": [ 151 | "from braket.aws import AwsSession\n", 152 | "from braket.jobs.image_uris import Framework, retrieve_image\n", 153 | "\n", 154 | "region = AwsSession().region\n", 155 | "image_uri = retrieve_image(Framework.PL_PYTORCH, region)\n", 156 | "print(image_uri)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "id": "e24786da-cc75-4bce-bc6f-e7700fb96beb", 162 | "metadata": {}, 163 | "source": [ 164 | "ハイブリッドジョブで Embedded Simulator を使用する場合、回路はジョブインスタンス上で実行されます。たくさんの量子ビットを持つ回路のシミュレーションなど、より大きな計算リソースを必要とするシミュレーションでは、多くのコア数や大容量メモリを持つジョブインスタンスを選択する必要があります。lightning.gpu のような GPUベースのシミュレータを使うには、GPU インスタンスを選択する必要があります。インスタンスを設定するには、`InstanceConfig` 引数を使います。利用可能なインスタンスタイプは、[開発者ガイド](https://docs.aws.amazon.com/braket/latest/APIReference/API_InstanceConfig.html) に記載されています。ここでは、汎用的なインスタンスタイプ (ml.m5.large) を使用することにしましょう。" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 7, 170 | "id": "9a71d324-6794-449f-836b-d4a6f7cdcd5e", 171 | "metadata": { 172 | "tags": [] 173 | }, 174 | "outputs": [], 175 | "source": [ 176 | "from braket.jobs.config import InstanceConfig\n", 177 | "\n", 178 | "instance_config = InstanceConfig(instanceType='ml.m5.large')" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "id": "9994143f-344f-46f4-bd51-ed436082de76", 184 | "metadata": {}, 185 | "source": [ 186 | "`device` 引数を使うと、簡単に異なるデバイスを切り替えることができます。次のセルでは、3 行のうち 1 行のコメントを外すと、Braket ローカルシミュレータ、PennyLane default.qubit シミュレータ、オンデマンドの状態ベクトルシミュレータ SV1 のいずれかを実行できます。" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 8, 192 | "id": "b1dda158-8e36-4b6a-8324-3ff286f51b00", 193 | "metadata": { 194 | "tags": [] 195 | }, 196 | "outputs": [], 197 | "source": [ 198 | "device=\"local:braket/braket.local.qubit\" # Using Braket local simulator\n", 199 | "# device=\"local:pennylane/default.qubit\" # Using Pennylane default.qubit simulator\n", 200 | "# device=\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\" # Using Braket on-demand SV1 " 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "id": "6150ac0e-a151-4b55-ab03-5b15c138f65a", 206 | "metadata": {}, 207 | "source": [ 208 | "それでは、ジョブを実行してみましょう!少なくとも、`device`, `source_module`, `entry_point` の引数を指定する必要があります。さらに以下のような他の引数でジョブをカスタマイズすることができます。\n", 209 | "- `device`: `\"local:/\"` の形式に従い Embedded Simulator を指定するか、または使用したい Braket オンデマンドシミュレータや QPU の ARN を指定します。これはアルゴリズムスクリプトの環境変数として保存されます。\n", 210 | "- `source_module`: アルゴリズムスクリプトを含むファイルまたは Python モジュールへのパスです。Braket Job を実行する際、コンテナにアップロードされます。\n", 211 | "- `entry_point`: source_module からの相対パスです。Braket Job の開始時に実行されるコード部分を指します。\n", 212 | "- `hyperparameters`: ハイパーパラメータをキーと値で表す Python 辞書です (オプション)。\n", 213 | "- `job_name`: ジョブを識別するためのユニークな文字列です。Braket Job コンソールとジョブ ARN に表示されます (オプション)。\n", 214 | "- `instance_config`: ジョブ実行時に使用するインスタンスの設定です。デフォルトでは `InstanceConfig(instanceType='ml.m5.large', volumeSizeInGb=30)` です (オプション)。\n", 215 | "- `image_uri`: Docker コンテナイメージへのパスです (オプション)。\n", 216 | "- `wait_until_complete`: True の場合、関数呼び出しはジョブが完了するまで待機し、さらにローカルコンソールにログを出力します。そうでない場合は、非同期で実行されます。デフォルトは False です (オプション)。" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 9, 222 | "id": "6ac8d28e-fe40-4e75-b4fc-8580a446236e", 223 | "metadata": { 224 | "tags": [] 225 | }, 226 | "outputs": [], 227 | "source": [ 228 | "import time\n", 229 | "from braket.aws import AwsQuantumJob\n", 230 | "\n", 231 | "job = AwsQuantumJob.create(\n", 232 | " device=device,\n", 233 | " source_module=\"qaoa\",\n", 234 | " entry_point=\"qaoa.qaoa_algorithm\",\n", 235 | " job_name=\"embedded-simulation-\" + str(int(time.time())),\n", 236 | " hyperparameters=hyperparameters,\n", 237 | " instance_config=instance_config,\n", 238 | " image_uri=image_uri,\n", 239 | " wait_until_complete=False,\n", 240 | ")" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 10, 246 | "id": "1579ee09-d2c2-4218-b93a-80de20cfad7a", 247 | "metadata": { 248 | "tags": [] 249 | }, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "{'params': [[0.9170388720505324, 0.7204929371752304, 1.4528933994269753], [1.3895487869726206, 0.9665264386809151, -0.47009700306676805]], 'cost': -0.5536775832039885}\n" 256 | ] 257 | } 258 | ], 259 | "source": [ 260 | "# このセルの実行には 6 分ほどかかります。\n", 261 | "print(job.result())" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "id": "176af925-d28c-4b81-8ea1-68b4e338f2ae", 267 | "metadata": {}, 268 | "source": [ 269 | "## 勾配計算方法のカスタマイズ\n", 270 | "量子回路の変分パラメータに対するコスト関数の勾配を計算する一般的な方法として、[パラメータシフト法](https://pennylane.ai/qml/glossary/parameter_shift.html)があります。パラメータシフト法では、パラメータをシフトした回路を複数回実行することで、勾配を正確に計算することができます。しかし,SV1 のような並列性の高いシミュレータを用いない限り,シフトされた回路をすべて実行するのは非常に時間がかかります。またその場合でも、回路数はパラメータ数に対して線形に増加します。一方,随伴微分法などの他の勾配法では,必要なメモリ量が増える代わりに,回路の実行回数を少なくすることができます。\n", 271 | "\n", 272 | "例えば、PennyLane の default.qubit シミュレータでは、ハイパーパラメータに `diff_method` 変数を指定することで 随伴微分法を使用することができます。なお、Amazon Braket のオンデマントシミュレータでは、PennyLane のパラメータシフト法しか使えません。" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": 11, 278 | "id": "98f799f3-401d-49cf-b928-018165b8612e", 279 | "metadata": { 280 | "tags": [] 281 | }, 282 | "outputs": [], 283 | "source": [ 284 | "hyperparameters={\n", 285 | " \"n_nodes\": 6, \n", 286 | " \"n_edges\": 8, \n", 287 | " \"n_layers\": 3,\n", 288 | " \"iterations\": 10,\n", 289 | " \"stepsize\": 0.1,\n", 290 | " \"seed\": 42,\n", 291 | " \"diff_method\": \"adjoint\",\n", 292 | "}" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 12, 298 | "id": "e60d499a-4afe-4af7-9024-fca6bbc3ccca", 299 | "metadata": { 300 | "tags": [] 301 | }, 302 | "outputs": [], 303 | "source": [ 304 | "job = AwsQuantumJob.create(\n", 305 | " device=\"local:pennylane/default.qubit\",\n", 306 | " source_module=\"qaoa\",\n", 307 | " entry_point=\"qaoa.qaoa_algorithm\",\n", 308 | " job_name=\"embedded-simulation-\" + str(int(time.time())),\n", 309 | " hyperparameters=hyperparameters,\n", 310 | " instance_config=instance_config,\n", 311 | " image_uri=image_uri,\n", 312 | " wait_until_complete=False,\n", 313 | ")" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": 13, 319 | "id": "af27f6db-534f-41f8-8f78-aacd0c5c8e28", 320 | "metadata": { 321 | "tags": [] 322 | }, 323 | "outputs": [ 324 | { 325 | "name": "stdout", 326 | "output_type": "stream", 327 | "text": [ 328 | "{'params': [[0.9170388720505318, 0.7204929371752299, 1.452893399426975], [1.3895487869726204, 0.9665264386809148, -0.470097003066768]], 'cost': -0.55367758320399}\n" 329 | ] 330 | } 331 | ], 332 | "source": [ 333 | "# このセルの実行には、6分ほどかかります。\n", 334 | "print(job.result())" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "id": "6b41ccd0-f782-4d91-97ab-5d0940db73a5", 340 | "metadata": {}, 341 | "source": [ 342 | "## `lightning.gpu` と cuQuantum を用いたシミュレーションの加速\n", 343 | "PyTorch と TensorFlow の[ジョブコンテナ](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-script-environment.html?tag=local002-20)には、[NVIDIA cuQuantum ライブラリ](https://developer.nvidia.com/cuquantum-sdk)と PennyLane の [GPU シミュレータ](https://github.com/PennyLaneAI/pennylane-lightning-gpu)である `lightning.gpu` が事前に設定されています。GPU シミュレータは、より大きな回路のシミュレーションを加速し、一定時間内にシミュレーションできる量子ビットの数を増やします。`lightning.gpu` を使用するには、GPU インスタンスを選択する必要があります。Braket Jobs は `lightning.gpu` と互換性のある以下ののインスタンスタイプをサポートしています。\n", 344 | "- p3.2xlarge\n", 345 | "- p3.8xlarge\n", 346 | "- p3.16xlarge" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 14, 352 | "id": "49884537-d276-4c3d-89d2-a9693fe1d461", 353 | "metadata": { 354 | "tags": [] 355 | }, 356 | "outputs": [], 357 | "source": [ 358 | "instance_config = InstanceConfig(instanceType='ml.p3.2xlarge')" 359 | ] 360 | }, 361 | { 362 | "cell_type": "markdown", 363 | "id": "6ac75ffc-3394-4d5e-96ff-b95126413580", 364 | "metadata": {}, 365 | "source": [ 366 | "また、GPU シミュレータは、パラメータシフト法と比較して勾配評価を大幅に高速化できる 随伴微分法もサポートしています。以下では、QAOA を使用して 22 ノードの Max-Clique 問題を解くジョブを作成します。このジョブの実行には 22 量子ビットを必要とします。各最適化にかかる時間は、`lightning.gpu` が約 1 分、CPU ベースのシミュレータである `lightning.qubit` が約 12 分です。この実行時間は、回路サイズ、問題の種類、計算リソースによって異なります。問題やインスタンスが変わると、パフォーマンスの挙動も変わる可能性があります。一般的に、CPU ベースのシミュレータは小さな回路の実行に適しており、GPU ベースのシミュレータは大きな回路に適しています。" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": 15, 372 | "id": "f34e24cb-cdbf-46ff-b681-2a8cbc403742", 373 | "metadata": { 374 | "tags": [] 375 | }, 376 | "outputs": [], 377 | "source": [ 378 | "hyperparameters={\n", 379 | " \"n_nodes\": 22, \n", 380 | " \"n_edges\": 150, \n", 381 | " \"n_layers\": 3,\n", 382 | " \"iterations\": 1,\n", 383 | " \"stepsize\": 0.1,\n", 384 | " \"seed\": 42,\n", 385 | " \"diff_method\": \"adjoint\",\n", 386 | "}" 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "id": "e63a09f5-485c-4f1c-a2bb-5cb739bfdc46", 392 | "metadata": {}, 393 | "source": [ 394 | "注意: 次のセルは、デフォルトのリソース制限では完了できない場合があります。アカウントの制限を増やすためには、[AWS サポート](https://support.console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase)までご連絡ください。" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": 18, 400 | "id": "90516e3e-5eee-40b7-b58f-e6c4c818da10", 401 | "metadata": { 402 | "tags": [] 403 | }, 404 | "outputs": [], 405 | "source": [ 406 | "# job = AwsQuantumJob.create(\n", 407 | "# device=\"local:pennylane/lightning.gpu\",\n", 408 | "# source_module=\"qaoa\",\n", 409 | "# entry_point=\"qaoa.qaoa_algorithm\",\n", 410 | "# job_name=\"embedded-simulation-\" + str(int(time.time())),\n", 411 | "# hyperparameters=hyperparameters,\n", 412 | "# instance_config=instance_config,\n", 413 | "# image_uri=image_uri,\n", 414 | "# wait_until_complete=False,\n", 415 | "# )" 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": 19, 421 | "id": "3ac309d5-69df-4e22-98ea-134327b4e111", 422 | "metadata": { 423 | "tags": [] 424 | }, 425 | "outputs": [], 426 | "source": [ 427 | "# このセルの実行には、 9 分ほどかかります。\n", 428 | "# print(job.result())" 429 | ] 430 | }, 431 | { 432 | "cell_type": "markdown", 433 | "id": "0c63d2c8-4b0c-4eaa-bd19-be9c52f9f20f", 434 | "metadata": {}, 435 | "source": [ 436 | "## ローカルモードによるデバッグ\n", 437 | "ジョブを投入する前に、ローカルでプログラムをデバッグしておくと便利なことがよくあります。Embedded Simulator をローカル環境で実行することで、テストやデバッグを迅速に行うことができます。この機能を使用するには、プログラミング環境に Docker がインストールされている必要があります。 Amazon Braket ノートブックには Docker がプリインストールされていますが、ローカルで、例えばノート PC でコードをテストしたい場合は、Docker をインストールする必要があります。詳細な手順は[こちら](https://docs.docker.com/get-docker/)をご確認ください。\n", 438 | "\n", 439 | "ローカルモードでは、ローカル環境にコンテナが作成され、そのコンテナ上でアルゴリズムが実行されます。ローカルモードでジョブを実行するには、Docker デーモンが起動していることを確認します。Amazon Braket ノートブックインスタンスを使用する場合は、既にこの準備は完了しています。その後、`AwsQuantumJob` の代わりに `LocalQuantumJob` を作成します。ローカルジョブは常に同期して実行され、ログを表示するので、`wait_until_complete` 引数はありません。ローカルモードのジョブはローカル環境で実行されるため、 `instance_config` 引数もありません。ローカルジョブの初回作成時は、コンテナを構築する必要があるため、時間が少しかかりますが、その後の実行はより高速になります。なお、ローカルジョブは、Amazon Braket コンソールには表示されません。ローカルモードでも、量子タスクを実際のデバイスに送信することはできますが、ローカルモード中に実際の QPU に対して実行しても、パフォーマンスのメリットは得られません。ローカルモードの詳細については、[開発者ガイド](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-local-mode.html)を参照してください。" 440 | ] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "execution_count": 20, 445 | "id": "44aa3b55-9ca1-45dc-80b0-775394f967d9", 446 | "metadata": { 447 | "tags": [] 448 | }, 449 | "outputs": [], 450 | "source": [ 451 | "hyperparameters={\n", 452 | " \"n_nodes\": 6, \n", 453 | " \"n_edges\": 8, \n", 454 | " \"n_layers\": 3,\n", 455 | " \"iterations\": 10,\n", 456 | " \"stepsize\": 0.1,\n", 457 | " \"seed\": 42,\n", 458 | " \"diff_method\": \"adjoint\",\n", 459 | "}" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 22, 465 | "id": "08f6ff5b-9f28-4b53-b016-e6f1f3e8eb29", 466 | "metadata": { 467 | "tags": [] 468 | }, 469 | "outputs": [ 470 | { 471 | "name": "stderr", 472 | "output_type": "stream", 473 | "text": [ 474 | "WARNING! Using --password via the CLI is insecure. Use --password-stdin.\n", 475 | "WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.\n", 476 | "Configure a credential helper to remove this warning. See\n", 477 | "https://docs.docker.com/engine/reference/commandline/login/#credentials-store\n", 478 | "\n", 479 | "Pulling docker container image. This may take a while.\n" 480 | ] 481 | }, 482 | { 483 | "name": "stdout", 484 | "output_type": "stream", 485 | "text": [ 486 | "Login Succeeded\n", 487 | "1.13.1-gpu-py39-cu117-ubuntu20.04: Pulling from amazon-braket-pytorch-jobs\n", 488 | "Digest: sha256:ab518e5af4141a9ce0cb9424c556e21a2fe8c4e4a5f2ff64cfcc85f3d46b3505\n", 489 | "Status: Image is up to date for 292282985366.dkr.ecr.us-east-1.amazonaws.com/amazon-braket-pytorch-jobs:1.13.1-gpu-py39-cu117-ubuntu20.04\n", 490 | "292282985366.dkr.ecr.us-east-1.amazonaws.com/amazon-braket-pytorch-jobs:1.13.1-gpu-py39-cu117-ubuntu20.04\n" 491 | ] 492 | }, 493 | { 494 | "name": "stderr", 495 | "output_type": "stream", 496 | "text": [ 497 | "Using the short-lived AWS credentials found in session. They might expire while running.\n" 498 | ] 499 | }, 500 | { 501 | "name": "stdout", 502 | "output_type": "stream", 503 | "text": [ 504 | "Boto3 Version: 1.26.64\n", 505 | "Beginning Setup\n", 506 | "Checking for Additional Requirements\n", 507 | "Additional Requirements Check Finished\n", 508 | "Running Code As Subprocess\n", 509 | "hyperparams: {'n_nodes': '6', 'n_edges': '8', 'n_layers': '3', 'iterations': '10', 'stepsize': '0.1', 'seed': '42', 'diff_method': 'adjoint'}\n", 510 | "Using local simulator: Default qubit PennyLane plugin\n", 511 | "number of observables: 13\n", 512 | "start optimizing...\n", 513 | "Metrics - timestamp=1684651535.0420568; Cost=4.570568368761232; iteration_number=0;\n", 514 | "Metrics - timestamp=1684651535.30743; Cost=2.6148149684630124; iteration_number=1;\n", 515 | "Metrics - timestamp=1684651535.5808728; Cost=1.0421622100067647; iteration_number=2;\n", 516 | "Metrics - timestamp=1684651535.845853; Cost=0.286949670853895; iteration_number=3;\n", 517 | "Metrics - timestamp=1684651536.109179; Cost=-0.25279908169178755; iteration_number=4;\n", 518 | "Metrics - timestamp=1684651536.3736026; Cost=-0.5599800238018436; iteration_number=5;\n", 519 | "Metrics - timestamp=1684651536.6450074; Cost=-0.5452012711678209; iteration_number=6;\n", 520 | "Metrics - timestamp=1684651536.9103014; Cost=-0.46554676264187245; iteration_number=7;\n", 521 | "Metrics - timestamp=1684651537.1744294; Cost=-0.4855957320274976; iteration_number=8;\n", 522 | "Metrics - timestamp=1684651537.4406106; Cost=-0.5284214035178895; iteration_number=9;\n", 523 | "Metrics - timestamp=1684651537.6996536; Cost=-0.55367758320399; iteration_number=10;\n", 524 | "Training Successful!!\n", 525 | "Code Run Finished\n", 526 | "cf6a43ac13d9aea5642898e2a20cfae779b4ae7dec346007de04981bdc0fda34\n" 527 | ] 528 | } 529 | ], 530 | "source": [ 531 | "from braket.jobs.local.local_job import LocalQuantumJob\n", 532 | "\n", 533 | "# このセルは、初回は3分ほど、その後は30秒ほどで終わります。\n", 534 | "job = LocalQuantumJob.create(\n", 535 | " device=\"local:pennylane/default.qubit\",\n", 536 | " source_module=\"qaoa\",\n", 537 | " entry_point=\"qaoa.qaoa_algorithm\",\n", 538 | " job_name=\"embedded-simulation-\" + str(int(time.time())),\n", 539 | " hyperparameters=hyperparameters,\n", 540 | " image_uri=image_uri,\n", 541 | ")" 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "id": "ea388d9b-cd50-42dc-83cb-7df4d18a774a", 547 | "metadata": {}, 548 | "source": [ 549 | "## まとめ\n", 550 | "このノートブックでは、Hybrid Jobs の Embedded Simulator の使い方を紹介しました。より詳しく知りたい方は、[ドキュメント](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html)か他のサンプルノートブックをご参照ください。" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": null, 556 | "id": "6ba38094-5324-4d76-b801-77a370e56979", 557 | "metadata": {}, 558 | "outputs": [], 559 | "source": [] 560 | } 561 | ], 562 | "metadata": { 563 | "kernelspec": { 564 | "display_name": "conda_braket", 565 | "language": "python", 566 | "name": "conda_braket" 567 | }, 568 | "language_info": { 569 | "codemirror_mode": { 570 | "name": "ipython", 571 | "version": 3 572 | }, 573 | "file_extension": ".py", 574 | "mimetype": "text/x-python", 575 | "name": "python", 576 | "nbconvert_exporter": "python", 577 | "pygments_lexer": "ipython3", 578 | "version": "3.10.11" 579 | } 580 | }, 581 | "nbformat": 4, 582 | "nbformat_minor": 5 583 | } 584 | -------------------------------------------------------------------------------- /workshop/hybrid_jobs/0_Creating_your_first_Hybrid_Job/Creating_your_first_Hybrid_Job.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6ff3fe20-875c-4012-a88c-954ae4ed9044", 6 | "metadata": {}, 7 | "source": [ 8 | "# Amazon Braket Hybrid Jobs 入門\n", 9 | "\n", 10 | "このチュートリアルでは、Amazon Braket Hybrid Job を実行する方法を紹介します。始めに、1 つの量子ビットと 1 つのゲートのみを持つシンプルな回路を考えます。\n", 11 | "\n", 12 | "## 内容\n", 13 | "* セットアップ\n", 14 | "* ジョブで実行するアルゴリズムスクリプトの作成\n", 15 | "* スクリプトや関数の実行方法\n", 16 | "* Braket のシミュレータや QPU を使ったジョブの作成\n", 17 | "* ジョブの状態の確認\n", 18 | "* ジョブの結果を保存\n", 19 | "* 特定の AWS セッションの使用\n", 20 | "* QPU 上の優先的なジョブの実行\n", 21 | "* ローカルジョブを使用したスクリプトの迅速なテストおよびデバッグ\n", 22 | "* Braket コンソールを使用したジョブの作成" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "id": "40d94ecf-283f-4916-9369-3aae8faac4fa", 28 | "metadata": {}, 29 | "source": [ 30 | "## Braket ジョブを実行するためのセットアップ\n", 31 | "\n", 32 | "Amazon Braket Hybrid Jobsを初めて使用する場合、[適切な権限](https://docs.aws.amazon.com/braket/latest/developerguide/braket-manage-access.html#about-amazonbraketjobsexecution)を持つ IAM ロールを作成する必要があります。このロールはジョブがアルゴリズムを実行する際、お客様の代わりになってアクションを実行します。例えば、ジョブの結果を返すために S3 にアクセスさせるかどうかなどをこの IAM ロールで指定します。ロールの作成 / 確認を行うには、Braket Console の左メニューから Permissions タブにアクセスしてください。\n", 33 | "\n", 34 | "## アルゴリズムスクリプトの作成\n", 35 | "\n", 36 | "Braket Job を作成するには、まず実行するための Python スクリプトが必要です。今回の例では、`algorithm_script.py` にあたります。以下のセルにその中身を載せています。\n", 37 | "\n", 38 | "これを見ると、各回路には、ランダムな角度の $X$ 回転ゲートが 1 つだけあり、角度を変えて 5 回繰り返されることがわかります。なお、このアルゴリズムスクリプトでは、バックエンドの Amazon Braket デバイス の ARN を明示的に指定していません。代わりに、ジョブの作成時にアルゴリズムスクリプトに渡される環境変数 `os.environ[\"AMZN_BRAKET_DEVICE_ARN\"]` として指定しています。" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "id": "d5dfbfe8-c542-4f77-a5a8-6aa59c1d638d", 44 | "metadata": {}, 45 | "source": [ 46 | "#### このセルはアルゴリズムスクリプトのコピーです。\n", 47 | "\n", 48 | "```python\n", 49 | "\n", 50 | "import os\n", 51 | "import numpy as np\n", 52 | "\n", 53 | "from braket.aws import AwsDevice\n", 54 | "from braket.circuits import Circuit\n", 55 | "from braket.jobs import save_job_result\n", 56 | "from braket.tracking import Tracker\n", 57 | "\n", 58 | "t = Tracker().start()\n", 59 | "\n", 60 | "print(\"Test job started!\")\n", 61 | "\n", 62 | "# Use the device declared in the creation script\n", 63 | "device = AwsDevice(os.environ[\"AMZN_BRAKET_DEVICE_ARN\"])\n", 64 | "\n", 65 | "counts_list = []\n", 66 | "angle_list = []\n", 67 | "for _ in range(5):\n", 68 | " angle = np.pi * np.random.randn()\n", 69 | " random_circuit = Circuit().rx(0, angle)\n", 70 | "\n", 71 | " task = device.run(random_circuit, shots=100)\n", 72 | " counts = task.result().measurement_counts\n", 73 | "\n", 74 | " angle_list.append(angle)\n", 75 | " counts_list.append(counts)\n", 76 | " print(counts)\n", 77 | "\n", 78 | "# Save the variables of interest so that we can access later\n", 79 | "save_job_result({\"counts\": counts_list, \"angle\": angle_list, \"estimated cost\": t.qpu_tasks_cost() + t.simulator_tasks_cost()})\n", 80 | "\n", 81 | "print(\"Test job completed!\")\n", 82 | "```" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "id": "a32a6b41-5d5b-4206-8074-1440ea933f78", 88 | "metadata": {}, 89 | "source": [ 90 | "## ジョブを作成する\n", 91 | "\n", 92 | "スクリプトが書けたら、`AwsQuantumJob`で Braket Job を作成することができます。ジョブが作成されると、Amazon Braket はジョブインスタンス (EC2 ベース) を起動し、Docker コンテナ上でアルゴリズムスクリプトを実行します。その他の設定は引数として指定することができます。ジョブをカスタマイズする方法については、[開発者ガイド](https://docs.aws.amazon.com/braket/latest/developerguide/what-is-braket.html)や他のサンプルノートブックを参照してください。\n", 93 | "\n", 94 | "今回の例では、`AwsQuantumJob` に以下の設定を行っています。\n", 95 | "- device: ジョブで使われる Braket シミュレータもしくは QPU の ARN です。アルゴリズムスクリプトへの環境変数として渡されます。\n", 96 | "- source_module: アルゴリズムスクリプトを含むファイルもしくは Python モジュールへのパスです。Braket Job を実行するコンテナにアップロードされます。\n", 97 | "- wait_until_complete (オプション): True の場合、ジョブが完了するまで待機し、ローカルのコンソールにログを出力します。False の場合、ジョブを非同期に実行します。デフォルト値は False です。" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 1, 103 | "id": "86f3f665-7c73-4b58-9e17-66a447a1e8b1", 104 | "metadata": { 105 | "tags": [] 106 | }, 107 | "outputs": [], 108 | "source": [ 109 | "from braket.aws import AwsQuantumJob" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 2, 115 | "id": "2b956890-cca3-4d13-b54f-3c80c7d61e5c", 116 | "metadata": { 117 | "tags": [] 118 | }, 119 | "outputs": [ 120 | { 121 | "name": "stdout", 122 | "output_type": "stream", 123 | "text": [ 124 | "Initializing Braket Job: arn:aws:braket:us-east-1:700863243650:job/braket-job-default-1684033674250\n", 125 | ".........................\n", 126 | "\u001b[34m2023-05-14 03:10:08,379 sagemaker-training-toolkit INFO No GPUs detected (normal if no gpus installed)\u001b[0m\n", 127 | "\u001b[34m2023-05-14 03:10:08,393 sagemaker-training-toolkit INFO No GPUs detected (normal if no gpus installed)\u001b[0m\n", 128 | "\u001b[34m2023-05-14 03:10:08,405 sagemaker-training-toolkit INFO No GPUs detected (normal if no gpus installed)\u001b[0m\n", 129 | "\u001b[34m2023-05-14 03:10:08,416 sagemaker-training-toolkit INFO Invoking user script\u001b[0m\n", 130 | "\u001b[34mTraining Env:\u001b[0m\n", 131 | "\u001b[34m{\n", 132 | " \"additional_framework_parameters\": {},\n", 133 | " \"channel_input_dirs\": {},\n", 134 | " \"current_host\": \"algo-1\",\n", 135 | " \"framework_module\": null,\n", 136 | " \"hosts\": [\n", 137 | " \"algo-1\"\n", 138 | " ],\n", 139 | " \"hyperparameters\": {},\n", 140 | " \"input_config_dir\": \"/opt/ml/input/config\",\n", 141 | " \"input_data_config\": {},\n", 142 | " \"input_dir\": \"/opt/ml/input\",\n", 143 | " \"is_master\": true,\n", 144 | " \"job_name\": \"bef49f5c-f5d7-43dc-9849-d08a5fc489a1\",\n", 145 | " \"log_level\": 20,\n", 146 | " \"master_hostname\": \"algo-1\",\n", 147 | " \"model_dir\": \"/opt/ml/model\",\n", 148 | " \"module_dir\": \"/opt/ml/code\",\n", 149 | " \"module_name\": \"braket_container\",\n", 150 | " \"network_interface_name\": \"eth0\",\n", 151 | " \"num_cpus\": 2,\n", 152 | " \"num_gpus\": 0,\n", 153 | " \"output_data_dir\": \"/opt/ml/output/data\",\n", 154 | " \"output_dir\": \"/opt/ml/output\",\n", 155 | " \"output_intermediate_dir\": \"/opt/ml/output/intermediate\",\n", 156 | " \"resource_config\": {\n", 157 | " \"current_host\": \"algo-1\",\n", 158 | " \"current_instance_type\": \"ml.m5.large\",\n", 159 | " \"current_group_name\": \"homogeneousCluster\",\n", 160 | " \"hosts\": [\n", 161 | " \"algo-1\"\n", 162 | " ],\n", 163 | " \"instance_groups\": [\n", 164 | " {\n", 165 | " \"instance_group_name\": \"homogeneousCluster\",\n", 166 | " \"instance_type\": \"ml.m5.large\",\n", 167 | " \"hosts\": [\n", 168 | " \"algo-1\"\n", 169 | " ]\n", 170 | " }\n", 171 | " ],\n", 172 | " \"network_interface_name\": \"eth0\"\n", 173 | " },\n", 174 | " \"user_entry_point\": \"braket_container.py\"\u001b[0m\n", 175 | "\u001b[34m}\u001b[0m\n", 176 | "\u001b[34mEnvironment variables:\u001b[0m\n", 177 | "\u001b[34mSM_HOSTS=[\"algo-1\"]\u001b[0m\n", 178 | "\u001b[34mSM_NETWORK_INTERFACE_NAME=eth0\u001b[0m\n", 179 | "\u001b[34mSM_HPS={}\u001b[0m\n", 180 | "\u001b[34mSM_USER_ENTRY_POINT=braket_container.py\u001b[0m\n", 181 | "\u001b[34mSM_FRAMEWORK_PARAMS={}\u001b[0m\n", 182 | "\u001b[34mSM_RESOURCE_CONFIG={\"current_group_name\":\"homogeneousCluster\",\"current_host\":\"algo-1\",\"current_instance_type\":\"ml.m5.large\",\"hosts\":[\"algo-1\"],\"instance_groups\":[{\"hosts\":[\"algo-1\"],\"instance_group_name\":\"homogeneousCluster\",\"instance_type\":\"ml.m5.large\"}],\"network_interface_name\":\"eth0\"}\u001b[0m\n", 183 | "\u001b[34mSM_INPUT_DATA_CONFIG={}\u001b[0m\n", 184 | "\u001b[34mSM_OUTPUT_DATA_DIR=/opt/ml/output/data\u001b[0m\n", 185 | "\u001b[34mSM_CHANNELS=[]\u001b[0m\n", 186 | "\u001b[34mSM_CURRENT_HOST=algo-1\u001b[0m\n", 187 | "\u001b[34mSM_MODULE_NAME=braket_container\u001b[0m\n", 188 | "\u001b[34mSM_LOG_LEVEL=20\u001b[0m\n", 189 | "\u001b[34mSM_FRAMEWORK_MODULE=\u001b[0m\n", 190 | "\u001b[34mSM_INPUT_DIR=/opt/ml/input\u001b[0m\n", 191 | "\u001b[34mSM_INPUT_CONFIG_DIR=/opt/ml/input/config\u001b[0m\n", 192 | "\u001b[34mSM_OUTPUT_DIR=/opt/ml/output\u001b[0m\n", 193 | "\u001b[34mSM_NUM_CPUS=2\u001b[0m\n", 194 | "\u001b[34mSM_NUM_GPUS=0\u001b[0m\n", 195 | "\u001b[34mSM_MODEL_DIR=/opt/ml/model\u001b[0m\n", 196 | "\u001b[34mSM_MODULE_DIR=/opt/ml/code\u001b[0m\n", 197 | "\u001b[34mSM_TRAINING_ENV={\"additional_framework_parameters\":{},\"channel_input_dirs\":{},\"current_host\":\"algo-1\",\"framework_module\":null,\"hosts\":[\"algo-1\"],\"hyperparameters\":{},\"input_config_dir\":\"/opt/ml/input/config\",\"input_data_config\":{},\"input_dir\":\"/opt/ml/input\",\"is_master\":true,\"job_name\":\"bef49f5c-f5d7-43dc-9849-d08a5fc489a1\",\"log_level\":20,\"master_hostname\":\"algo-1\",\"model_dir\":\"/opt/ml/model\",\"module_dir\":\"/opt/ml/code\",\"module_name\":\"braket_container\",\"network_interface_name\":\"eth0\",\"num_cpus\":2,\"num_gpus\":0,\"output_data_dir\":\"/opt/ml/output/data\",\"output_dir\":\"/opt/ml/output\",\"output_intermediate_dir\":\"/opt/ml/output/intermediate\",\"resource_config\":{\"current_group_name\":\"homogeneousCluster\",\"current_host\":\"algo-1\",\"current_instance_type\":\"ml.m5.large\",\"hosts\":[\"algo-1\"],\"instance_groups\":[{\"hosts\":[\"algo-1\"],\"instance_group_name\":\"homogeneousCluster\",\"instance_type\":\"ml.m5.large\"}],\"network_interface_name\":\"eth0\"},\"user_entry_point\":\"braket_container.py\"}\u001b[0m\n", 198 | "\u001b[34mSM_USER_ARGS=[]\u001b[0m\n", 199 | "\u001b[34mSM_OUTPUT_INTERMEDIATE_DIR=/opt/ml/output/intermediate\u001b[0m\n", 200 | "\u001b[34mPYTHONPATH=/opt/ml/code:/usr/local/bin:/usr/local/lib/python38.zip:/usr/local/lib/python3.8:/usr/local/lib/python3.8/lib-dynload:/usr/local/lib/python3.8/site-packages\u001b[0m\n", 201 | "\u001b[34mInvoking script with the following command:\u001b[0m\n", 202 | "\u001b[34m/usr/local/bin/python3.8 braket_container.py\u001b[0m\n", 203 | "\u001b[34mBoto3 Version: 1.26.64\u001b[0m\n", 204 | "\u001b[34mBeginning Setup\u001b[0m\n", 205 | "\u001b[34mChecking for Additional Requirements\u001b[0m\n", 206 | "\u001b[34mAdditional Requirements Check Finished\u001b[0m\n", 207 | "\u001b[34mRunning Code As Subprocess\u001b[0m\n", 208 | "\u001b[34mTest job started!!!!!\u001b[0m\n", 209 | "\u001b[34mCounter({'1': 82, '0': 18})\u001b[0m\n", 210 | "\u001b[34mMetrics - timestamp=1684033813.6415727; braket_tasks_cost=0.00375; iteration_number=0;\u001b[0m\n", 211 | "\u001b[34mCounter({'1': 96, '0': 4})\u001b[0m\n", 212 | "\u001b[34mMetrics - timestamp=1684033816.1763873; braket_tasks_cost=0.0075; iteration_number=1;\u001b[0m\n", 213 | "\u001b[34mCounter({'0': 99, '1': 1})\u001b[0m\n", 214 | "\u001b[34mMetrics - timestamp=1684033818.7527447; braket_tasks_cost=0.01125; iteration_number=2;\u001b[0m\n", 215 | "\u001b[34mCounter({'0': 66, '1': 34})\u001b[0m\n", 216 | "\u001b[34mMetrics - timestamp=1684033821.3189068; braket_tasks_cost=0.015; iteration_number=3;\u001b[0m\n", 217 | "\u001b[34mCounter({'0': 100})\u001b[0m\n", 218 | "\u001b[34mMetrics - timestamp=1684033824.0551062; braket_tasks_cost=0.01875; iteration_number=4;\u001b[0m\n", 219 | "\u001b[34mTest job completed!!!!!\u001b[0m\n", 220 | "\u001b[34mCode Run Finished\u001b[0m\n", 221 | "\u001b[34m2023-05-14 03:10:24,309 sagemaker-training-toolkit INFO Reporting training SUCCESS\u001b[0m\n" 222 | ] 223 | } 224 | ], 225 | "source": [ 226 | "# このセルの実行には 5 分ほどかかります\n", 227 | "job = AwsQuantumJob.create(\n", 228 | " device=\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\",\n", 229 | " source_module=\"algorithm_script.py\",\n", 230 | " wait_until_complete=True,\n", 231 | ")" 232 | ] 233 | }, 234 | { 235 | "cell_type": "markdown", 236 | "id": "b4447bf6-8509-4b0b-94d5-166f6aa06ea2", 237 | "metadata": {}, 238 | "source": [ 239 | "今回の例では、アルゴリズムは 1 つのファイルで定義されているため、`source_module` は `algorithm_script.py` です。アプリケーションによっては、ソースモジュールを他の方法で設定できます。例えば、ジョブの開始時に `algorithm_script.py` の一部だけを実行したい場合、その部分を `starting_function()` としてパッケージ化することも可能です。そして、`entry_point` という引数を追加して、その関数をエントリポイントとして割り当てます。" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 3, 245 | "id": "ae017676-5bc6-46f8-be3b-41c33732c259", 246 | "metadata": { 247 | "tags": [] 248 | }, 249 | "outputs": [], 250 | "source": [ 251 | "source_module = \"algorithm_script.py\"\n", 252 | "entry_point = \"algorithm_script:starting_function\"" 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "id": "fcc70403-c4b5-4d9c-9e8e-af5fef2f3a92", 258 | "metadata": {}, 259 | "source": [ 260 | "アルゴリズムスクリプトが他のファイルと依存関係を持つ場合、それらをすべて 1 つのフォルダ、例えば `algorithm_folder` に置くことができます。この場合、引数は次のようになります。" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": 4, 266 | "id": "2b0719a2-c456-4238-a966-e5f0738b0351", 267 | "metadata": { 268 | "tags": [] 269 | }, 270 | "outputs": [], 271 | "source": [ 272 | "source_module = \"algorithm_folder\"\n", 273 | "entry_point = \"algorithm_folder.algorithm_script:starting_function\"" 274 | ] 275 | }, 276 | { 277 | "cell_type": "markdown", 278 | "id": "db709966-af9c-474d-a2fb-e7afcae4542d", 279 | "metadata": {}, 280 | "source": [ 281 | "## ジョブの状態の確認と結果の取得\n", 282 | "\n", 283 | "Braket Job の状態は `job.state()` を呼び出すことで確認できます。状態は \"QUEUED\", \"RUNNING\", \"FAILED\", \"COMPLETED\", \"CANCELLING\", \"CANCELLED\" のいずれかとなります。" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 5, 289 | "id": "8d0e32e0-2961-4716-9e34-6af01ae2a340", 290 | "metadata": { 291 | "tags": [] 292 | }, 293 | "outputs": [ 294 | { 295 | "data": { 296 | "text/plain": [ 297 | "'COMPLETED'" 298 | ] 299 | }, 300 | "execution_count": 5, 301 | "metadata": {}, 302 | "output_type": "execute_result" 303 | } 304 | ], 305 | "source": [ 306 | "job.state()" 307 | ] 308 | }, 309 | { 310 | "cell_type": "markdown", 311 | "id": "f1b4a88a-65fb-4ea0-a1c1-fde27ee1164a", 312 | "metadata": {}, 313 | "source": [ 314 | "完了 (\"COMPLETED\") したら、`job.result()` を用いて結果を取得することができます。ログとメタデータも `job.logs()` と `job.metadata()` で取得できます。ジョブオブジェクトの参照を失った場合は、ジョブ ARN を使用して `job=AwsQuantumJob(\"your-job-arn\")` としていつでも再定義できます。ジョブ ARN は Amazon Braket Console で確認できます。デフォルトでは、ジョブ ARN は \"`arn:aws:braket:::job/`\" の形式です。" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 6, 320 | "id": "73b71ac7-91cd-461c-a3c5-6f532cf3c2f7", 321 | "metadata": { 322 | "tags": [] 323 | }, 324 | "outputs": [ 325 | { 326 | "name": "stdout", 327 | "output_type": "stream", 328 | "text": [ 329 | "counts: [{'1': 82, '0': 18}, {'1': 96, '0': 4}, {'0': 99, '1': 1}, {'1': 34, '0': 66}, {'0': 100}]\n", 330 | "angles: [2.2579830553408797, -2.8787011487593785, 0.09387639599223568, 5.137803481300752, -0.12194465950382408]\n" 331 | ] 332 | } 333 | ], 334 | "source": [ 335 | "results = job.result() # job.state() = \"COMPLETED\" となれば結果を返します\n", 336 | "print(\"counts: \", results[\"counts\"])\n", 337 | "print(\"angles: \", results[\"angles\"])" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 8, 343 | "id": "75ce9b6d-3a58-4275-ae49-5be407ad5d49", 344 | "metadata": { 345 | "tags": [] 346 | }, 347 | "outputs": [], 348 | "source": [ 349 | "# print(job.logs()) # ログを出力したい場合はコメントアウトを外してください" 350 | ] 351 | }, 352 | { 353 | "cell_type": "markdown", 354 | "id": "52e5c19a-3eb1-4acd-a91f-fd492aac1267", 355 | "metadata": {}, 356 | "source": [ 357 | "結果をローカルの環境にダウンロードすることもできます。" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 9, 363 | "id": "585057fb-2d6c-4147-b6ea-8964110fe25d", 364 | "metadata": { 365 | "tags": [] 366 | }, 367 | "outputs": [], 368 | "source": [ 369 | "job.download_result() # 結果をローカル環境にダウンロード" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 10, 375 | "id": "6106c2ef-18ac-4f9e-b56e-30b2dc65cda1", 376 | "metadata": { 377 | "tags": [] 378 | }, 379 | "outputs": [ 380 | { 381 | "name": "stdout", 382 | "output_type": "stream", 383 | "text": [ 384 | "Task Summary\n", 385 | "{'arn:aws:braket:::device/quantum-simulator/amazon/sv1': {'shots': 500, 'tasks': {'COMPLETED': 5}, 'execution_duration': 0.041, 'billed_execution_duration': 15.0}}\n", 386 | "Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).\n", 387 | "Estimated cost to run tasks in this job: 0.01875 USD\n" 388 | ] 389 | } 390 | ], 391 | "source": [ 392 | "print(\"Task Summary\")\n", 393 | "print(job.result()['task summary'])\n", 394 | "print('Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).')\n", 395 | "print(f\"Estimated cost to run tasks in this job: {job.result()['estimated cost']} USD\")" 396 | ] 397 | }, 398 | { 399 | "cell_type": "markdown", 400 | "id": "5ee0dae3-86e7-4370-b3ef-f4c0ee0dc7cf", 401 | "metadata": {}, 402 | "source": [ 403 | "## QPU 上で優先的にジョブを実行する\n", 404 | "\n", 405 | "Braket Jobs を使用すると、Amazon Braket で利用できる全ての QPU でハイブリッドアルゴリズムを実行することができます。QPU をデバイスとして選択すると、ジョブの実行中、QPU に優先的にアクセスできるようになります。ジョブの一部として作成される量子タスクは、デバイスのキューにある他のタスクよりも先に実行されます。これにより、特定のタスクが遅延したり、ジョブ実行中にデバイスのキャリブレーションに変動が生じるリスクを低減します。\n", 406 | "\n", 407 | "`AwsQuantumJob.create()` の device 引数を変更することで、SV1 シミュレータを QPU にシームレスに入れ替えることができます。例えば、以下のコードでは、Rigetti Aspen-M-3 デバイス上で優先アクセス権を持つジョブを作成します。\n", 408 | "\n", 409 | "
\n", 410 | "注意: 以下のセルは Rigetti Aspen-M-3 デバイスを使用しています。コメントを解除して実行する前に、デバイスが現在利用可能であることを確認してください。QPU の利用可能時間帯 は Amazon Braket コンソール画面の Devices ページで確認できます。\n", 411 | "
" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": null, 417 | "id": "baf97f0c-739a-4317-a555-183111cdbe96", 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "# qpu_job = AwsQuantumJob.create(\n", 422 | "# device=\"arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3\",\n", 423 | "# source_module=\"algorithm_script.py\",\n", 424 | "# wait_until_complete=False,\n", 425 | "# )" 426 | ] 427 | }, 428 | { 429 | "cell_type": "markdown", 430 | "id": "31b1ccbb-f4ae-4022-afd2-41e0cf1c7762", 431 | "metadata": {}, 432 | "source": [ 433 | "ジョブを作成すると、Amazon Braket はジョブを初期化する前に、QPU が実行可能になるのを待ちます。なお、Braket Job は、デバイスが利用可能な AWS リージョンを自動的に選択します。前述のように、指定されたデバイスは環境変数 `AMZN_BRAKET_DEVICE_ARN` でジョブに提供されます。スクリプト `algorithm_script.py` はこの変数を使って、使用する Braket デバイスを選択します。\n", 434 | "\n", 435 | "変分アルゴリズムでは通常、固定されたパラメータ付き回路が持つパラメータを更新する最適化処理が行われます。このようなアルゴリズムを QPU で実行する場合、パラメトリックコンパイルによってジョブの性能を向上させることができます。その際必要なのは、スクリプトで free parameters を使用してパラメータ付き回路を定義するだけです。このようにすると、Braket は回路を一度コンパイルし、コンパイル済み回路を管理するようになります。パラメータを更新する際は再コンパイルする必要がないため、実行時間が短縮されます。パラメータ化された回路を使用するスクリプトの例は `algorithm_script_parametrized_circuit.py` にあります。このスクリプトを`algorithm_script.py` の代わりに使用し、QPU にジョブを投げることでパラメトリックコンパイルを使用できます。Hybrid Jobs での [free parameters](https://docs.aws.amazon.com/braket/latest/developerguide/braket-constructing-circuit.html#braket-gates) と[パラメトリックコンパイル](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html)の使い方については、ドキュメントをご参照ください。" 436 | ] 437 | }, 438 | { 439 | "cell_type": "markdown", 440 | "id": "65390919-baa2-4676-abb6-12de4d83c35f", 441 | "metadata": {}, 442 | "source": [ 443 | "## AWS セッションについて\n", 444 | "\n", 445 | "Braket Jobs が Amazon S3 に結果を保存するデフォルトの場所は、AWS のセッション情報を提供することでカスタマイズすることができます。S3 バケットの名前は \"amazon-braket-\" で始まる必要があり、作成されるジョブと同じリージョンにある必要があります。" 446 | ] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": 11, 451 | "id": "b21290ff-0341-4be1-a89d-7d84074df06d", 452 | "metadata": { 453 | "tags": [] 454 | }, 455 | "outputs": [], 456 | "source": [ 457 | "from braket.aws import AwsSession\n", 458 | "\n", 459 | "# Set Amazon S3 bucket\n", 460 | "aws_session = AwsSession(default_bucket=\"amazon-braket-bucket-name\")" 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "id": "ca953d9a-7dde-43ec-a494-3edcf366ec1b", 466 | "metadata": {}, 467 | "source": [ 468 | "この S3 バケットを使って Braket Job を作成するには、`AwsQuantumJob.create()` の引数に `aws_session` を渡します。\n", 469 | "```\n", 470 | "job = AwsQuantumJob.create(\n", 471 | " device=\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\",\n", 472 | " source_module=\"algorithm_script.py\",\n", 473 | " aws_session=aws_session # using specific S3 bucket\n", 474 | ")\n", 475 | "```" 476 | ] 477 | }, 478 | { 479 | "cell_type": "markdown", 480 | "id": "d7530694-2c2b-44db-a1b6-89fa79eed964", 481 | "metadata": {}, 482 | "source": [ 483 | "## ローカルジョブを利用してデバッグする\n", 484 | "\n", 485 | "コードのテストやデバッグをより迅速に行うために、お客様の環境でジョブをローカルに実行することができます。この機能を使用するには、ローカル環境に Docker がインストールされている必要があります。Amazon Braket Notebook には、Docker がプリインストールされているため、ホストされたノートブックでローカルジョブを即座にテストすることができます。ローカル環境に Docker をインストールするには、以下の[手順](https://docs.docker.com/get-docker/)を参照ください。ローカルジョブを初めて作成する場合、コンテナを構築する必要があるため、時間がかかります。その後の実行はより早くなります。ローカルジョブは Amazon Braket Console には表示されないことに注意してください。\n", 486 | "\n", 487 | "ローカルでジョブを実行するには、Docker デーモンが起動していることを確認し、`AwsQuantumJob` の代わりに `LocalQuantumJob` を作成するだけです。ローカルジョブは常に同期的に実行され、ログが表示されます。" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 12, 493 | "id": "44a576ba-6058-44a5-ac87-6816740d2465", 494 | "metadata": { 495 | "tags": [] 496 | }, 497 | "outputs": [ 498 | { 499 | "name": "stderr", 500 | "output_type": "stream", 501 | "text": [ 502 | "WARNING! Using --password via the CLI is insecure. Use --password-stdin.\n", 503 | "WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.\n", 504 | "Configure a credential helper to remove this warning. See\n", 505 | "https://docs.docker.com/engine/reference/commandline/login/#credentials-store\n", 506 | "\n", 507 | "Pulling docker container image. This may take a while.\n" 508 | ] 509 | }, 510 | { 511 | "name": "stdout", 512 | "output_type": "stream", 513 | "text": [ 514 | "Login Succeeded\n", 515 | "1.0-cpu-py39-ubuntu22.04: Pulling from amazon-braket-base-jobs\n", 516 | "74ac377868f8: Pulling fs layer\n", 517 | "7fe9b8f01457: Pulling fs layer\n", 518 | "780db72835a0: Pulling fs layer\n", 519 | "c48699d0db25: Pulling fs layer\n", 520 | "eacfd7fc3878: Pulling fs layer\n", 521 | "d032eab7e852: Pulling fs layer\n", 522 | "354743fa6126: Pulling fs layer\n", 523 | "740069ceea3b: Pulling fs layer\n", 524 | "d31f1b3318e6: Pulling fs layer\n", 525 | "d6075f43bf82: Pulling fs layer\n", 526 | "eb0da417065f: Pulling fs layer\n", 527 | "6c747b12e5cf: Pulling fs layer\n", 528 | "14facc2388ef: Pulling fs layer\n", 529 | "ea3a15f84b42: Pulling fs layer\n", 530 | "fd38d897c417: Pulling fs layer\n", 531 | "3d6e4b48f11e: Pulling fs layer\n", 532 | "c48699d0db25: Waiting\n", 533 | "eacfd7fc3878: Waiting\n", 534 | "d032eab7e852: Waiting\n", 535 | "354743fa6126: Waiting\n", 536 | "740069ceea3b: Waiting\n", 537 | "d31f1b3318e6: Waiting\n", 538 | "d6075f43bf82: Waiting\n", 539 | "eb0da417065f: Waiting\n", 540 | "6c747b12e5cf: Waiting\n", 541 | "14facc2388ef: Waiting\n", 542 | "ea3a15f84b42: Waiting\n", 543 | "3d6e4b48f11e: Waiting\n", 544 | "fd38d897c417: Waiting\n", 545 | "780db72835a0: Verifying Checksum\n", 546 | "780db72835a0: Download complete\n", 547 | "74ac377868f8: Verifying Checksum\n", 548 | "74ac377868f8: Download complete\n", 549 | "c48699d0db25: Verifying Checksum\n", 550 | "c48699d0db25: Download complete\n", 551 | "eacfd7fc3878: Verifying Checksum\n", 552 | "eacfd7fc3878: Download complete\n", 553 | "d032eab7e852: Verifying Checksum\n", 554 | "d032eab7e852: Download complete\n", 555 | "354743fa6126: Verifying Checksum\n", 556 | "354743fa6126: Download complete\n", 557 | "740069ceea3b: Verifying Checksum\n", 558 | "740069ceea3b: Download complete\n", 559 | "d6075f43bf82: Verifying Checksum\n", 560 | "d6075f43bf82: Download complete\n", 561 | "eb0da417065f: Verifying Checksum\n", 562 | "eb0da417065f: Download complete\n", 563 | "74ac377868f8: Pull complete\n", 564 | "d31f1b3318e6: Verifying Checksum\n", 565 | "d31f1b3318e6: Download complete\n", 566 | "6c747b12e5cf: Verifying Checksum\n", 567 | "6c747b12e5cf: Download complete\n", 568 | "ea3a15f84b42: Verifying Checksum\n", 569 | "ea3a15f84b42: Download complete\n", 570 | "fd38d897c417: Download complete\n", 571 | "3d6e4b48f11e: Verifying Checksum\n", 572 | "3d6e4b48f11e: Download complete\n", 573 | "7fe9b8f01457: Verifying Checksum\n", 574 | "7fe9b8f01457: Download complete\n", 575 | "14facc2388ef: Verifying Checksum\n", 576 | "14facc2388ef: Download complete\n", 577 | "7fe9b8f01457: Pull complete\n", 578 | "780db72835a0: Pull complete\n", 579 | "c48699d0db25: Pull complete\n", 580 | "eacfd7fc3878: Pull complete\n", 581 | "d032eab7e852: Pull complete\n", 582 | "354743fa6126: Pull complete\n", 583 | "740069ceea3b: Pull complete\n", 584 | "d31f1b3318e6: Pull complete\n", 585 | "d6075f43bf82: Pull complete\n", 586 | "eb0da417065f: Pull complete\n", 587 | "6c747b12e5cf: Pull complete\n", 588 | "14facc2388ef: Pull complete\n", 589 | "ea3a15f84b42: Pull complete\n", 590 | "fd38d897c417: Pull complete\n", 591 | "3d6e4b48f11e: Pull complete\n", 592 | "Digest: sha256:03a291d3c46ea412fa4213ac1fef6a11cbce7a1cd124205b2316e0c6b531fca4\n", 593 | "Status: Downloaded newer image for 292282985366.dkr.ecr.us-east-1.amazonaws.com/amazon-braket-base-jobs:1.0-cpu-py39-ubuntu22.04\n", 594 | "292282985366.dkr.ecr.us-east-1.amazonaws.com/amazon-braket-base-jobs:1.0-cpu-py39-ubuntu22.04\n" 595 | ] 596 | }, 597 | { 598 | "name": "stderr", 599 | "output_type": "stream", 600 | "text": [ 601 | "Using the short-lived AWS credentials found in session. They might expire while running.\n" 602 | ] 603 | }, 604 | { 605 | "name": "stdout", 606 | "output_type": "stream", 607 | "text": [ 608 | "Boto3 Version: 1.26.64\n", 609 | "Beginning Setup\n", 610 | "Checking for Additional Requirements\n", 611 | "Additional Requirements Check Finished\n", 612 | "Running Code As Subprocess\n", 613 | "Test job started!!!!!\n", 614 | "Counter({'0': 86, '1': 14})\n", 615 | "Metrics - timestamp=1684037687.144999; braket_tasks_cost=0.00375; iteration_number=0;\n", 616 | "Counter({'0': 96, '1': 4})\n", 617 | "Metrics - timestamp=1684037689.732998; braket_tasks_cost=0.0075; iteration_number=1;\n", 618 | "Counter({'0': 92, '1': 8})\n", 619 | "Metrics - timestamp=1684037692.3552556; braket_tasks_cost=0.01125; iteration_number=2;\n", 620 | "Counter({'1': 52, '0': 48})\n", 621 | "Metrics - timestamp=1684037695.0975327; braket_tasks_cost=0.015; iteration_number=3;\n", 622 | "Counter({'1': 90, '0': 10})\n", 623 | "Metrics - timestamp=1684037697.72457; braket_tasks_cost=0.01875; iteration_number=4;\n", 624 | "Test job completed!!!!!\n", 625 | "Code Run Finished\n", 626 | "c00555bbebdf8f543ff74f8e7bc998c5c433d7a08ef29d6d4371bdd3d728cee0\n" 627 | ] 628 | } 629 | ], 630 | "source": [ 631 | "from braket.jobs.local.local_job import LocalQuantumJob\n", 632 | "\n", 633 | "# This cell should take about 2 min\n", 634 | "job = LocalQuantumJob.create(\n", 635 | " device=\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\",\n", 636 | " source_module=\"algorithm_script.py\",\n", 637 | ")" 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "execution_count": 13, 643 | "id": "2888d338-4b33-47b1-a4d7-9b3724084731", 644 | "metadata": { 645 | "tags": [] 646 | }, 647 | "outputs": [ 648 | { 649 | "name": "stdout", 650 | "output_type": "stream", 651 | "text": [ 652 | "Task Summary\n", 653 | "{'arn:aws:braket:::device/quantum-simulator/amazon/sv1': {'shots': 500, 'tasks': {'COMPLETED': 5}, 'execution_duration': 0.125, 'billed_execution_duration': 15.0}}\n", 654 | "Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).\n", 655 | "Estimated cost to run tasks in this job: 0.01875 USD\n" 656 | ] 657 | } 658 | ], 659 | "source": [ 660 | "print(\"Task Summary\")\n", 661 | "print(job.result()['task summary'])\n", 662 | "print('Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).')\n", 663 | "print(f\"Estimated cost to run tasks in this job: {job.result()['estimated cost']} USD\")" 664 | ] 665 | }, 666 | { 667 | "cell_type": "markdown", 668 | "id": "21009565-f926-4323-8c4d-14a1c33421a4", 669 | "metadata": {}, 670 | "source": [ 671 | "## Braket コンソール上でジョブを作成する\n", 672 | "\n", 673 | "`AwsQuantumJob.create` を使用してプログラムで Braket Job を作成する以外に、Braket コンソールでジョブを作成するオプションがあります。[こちらのリンク](https://us-west-2.console.aws.amazon.com/braket/home#/job/create) を参照して、\\\"Create job\\\" ページをご確認ください。まず、新しいジョブにユニークな名前をつけます。デフォルトでは、Amazon Braket は AmazonBraketJobsExecutionRole に、ジョブ実行に必要なすべての権限が存在することを確認します。ジョブのすべての入力と出力が保存されるデフォルトの S3 フォルダは、`amazon-braket--/jobs/` という形式です。S3 バケットとフォルダが存在しない場合、Amazon Braket がお客様の代わりに作成します。これらのデフォルト設定は、\\\"Advanced settings\\\" タブでカスタマイズすることができます。\n", 674 | "\n", 675 | "
" 676 | ] 677 | }, 678 | { 679 | "cell_type": "markdown", 680 | "id": "bfa08567-2ca6-4414-88f1-958c393902c4", 681 | "metadata": {}, 682 | "source": [ 683 | "次に、ジョブのアルゴリズムスクリプトを選択します。スクリプトは、単一のファイルとしてコンソールで直接アップロードすることができます。アルゴリズムスクリプトに付随するヘルパー関数やその他の依存関係など、多くのファイルがある場合は、S3 バケットにファイルをアップロードして S3 フォルダを提供するオプションがあります。\n", 684 | "\n", 685 | "
" 686 | ] 687 | }, 688 | { 689 | "cell_type": "markdown", 690 | "id": "f098c221-415d-4a37-be21-988bc73a9d76", 691 | "metadata": {}, 692 | "source": [ 693 | "次に、ジョブに使用する Braket シミュレータまたは QPU の設定を行います。最後に、ハイパーパラメータとデータの入力、チェックポイントと出力データのデフォルトの場所をカスタマイズできます。これらの使用例については、他のノートブックの例で詳しく説明します。全ての設定を終えたら、\\\"Create job\\\" ボタンをクリックして、ジョブを作成します。これで、Braket コンソールでジョブ状態を確認できるようになりました。\n", 694 | "\n", 695 | "
" 696 | ] 697 | }, 698 | { 699 | "cell_type": "markdown", 700 | "id": "ea1720cd-65cb-416f-bbbd-e654fdbe4a23", 701 | "metadata": {}, 702 | "source": [ 703 | "## まとめ\n", 704 | "\n", 705 | "このチュートリアルでは、Amazon Braket SDK を使用し、5 つのシンプルな回路で最初の Braket Job を作成しました。また、ジョブの Amazon S3 フォルダと AWS リージョンを変更する方法と、結果を保存する方法を学びました。シミュレータや QPU で実行するためにデバイスをシームレスに変更する方法を学びました。ローカルモードを使って、コードを素早くテストしました。最後に、Braket コンソールを使って同じジョブを作成しました。" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "execution_count": null, 711 | "id": "1d9371db-cbf3-4920-820a-4d3ce264c392", 712 | "metadata": {}, 713 | "outputs": [], 714 | "source": [] 715 | } 716 | ], 717 | "metadata": { 718 | "kernelspec": { 719 | "display_name": "conda_braket", 720 | "language": "python", 721 | "name": "conda_braket" 722 | }, 723 | "language_info": { 724 | "codemirror_mode": { 725 | "name": "ipython", 726 | "version": 3 727 | }, 728 | "file_extension": ".py", 729 | "mimetype": "text/x-python", 730 | "name": "python", 731 | "nbconvert_exporter": "python", 732 | "pygments_lexer": "ipython3", 733 | "version": "3.10.11" 734 | } 735 | }, 736 | "nbformat": 4, 737 | "nbformat_minor": 5 738 | } 739 | -------------------------------------------------------------------------------- /workshop/qiskit/0_Getting_Started.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "54db101c-0bfd-46b2-9398-62224f69b512", 6 | "metadata": {}, 7 | "source": [ 8 | "# Amazon Braket で Qiskit を実行する" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "e861abc5-0649-483e-9eac-04130922464b", 15 | "metadata": { 16 | "tags": [] 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "# このノートブックの実行料金を見積もるために Braket SDK Cost Tracking を使用します\n", 21 | "from braket.tracking import Tracker\n", 22 | "t = Tracker().start()" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "id": "3d79f556-9a28-4dc3-9bfc-4d0b55be64aa", 28 | "metadata": {}, 29 | "source": [ 30 | "お客様も、ここ数年で量子コンピュータを学んだ多くの方と同じように、2017 年に初めてリリースされたオープンソースの量子ソフトウェア開発キット (SDK) である Qiskit を使って、量子回路をプログラミングする方法を学んだかもしれません。\n", 31 | "[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", 32 | "\n", 33 | "**注意** ローカル環境でこのノートブックを実行している場合 (つまりBraket コンソールから実行していない場合)、Braket デバイスにアクセスするために、最初に AWS アカウントが適切に構成されていることを確認する必要があります。[こちらのチュートリアル](https://aws.amazon.com/blogs/quantum-computing/setting-up-your-local-development-environment-in-amazon-braket/)で、その手順をご確認ください。" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "f4f2f12a-d87a-4f4d-b018-f465b383e19a", 39 | "metadata": {}, 40 | "source": [ 41 | "## Qiskit から Braket デバイスにアクセスする\n", 42 | "\n", 43 | "Amazon Braket のバックエンドデバイスはかなり種類が多いため、それぞれのおすすめユースケースを 1 つずつ説明していきます。" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "id": "d3df9002-d332-4d31-abdb-eddf1bb27948", 49 | "metadata": {}, 50 | "source": [ 51 | "### 量子シミュレータ\n", 52 | "\n", 53 | "まず、ローカルシミュレータから始めましょう。これはローカル環境で動作する量子フル状態ベクトルシミュレータです。ローカル環境とは、この Jupyter ノートブックの実行場所 (例えば、ローカル開発環境や Braket コンソール上のノートブックインスタンスなど) を指します。\n", 54 | "\n", 55 | "**推奨ユースケース:** 最大 12 量子ビットのノイズなし回路" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 2, 61 | "id": "bcb65696-6018-4bbc-aa56-1cfefa0f80fa", 62 | "metadata": { 63 | "tags": [] 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "from qiskit_braket_provider import BraketLocalBackend\n", 68 | "\n", 69 | "local_simulator = BraketLocalBackend()" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "id": "413de274-7c4b-402a-9140-6064d8430264", 75 | "metadata": {}, 76 | "source": [ 77 | "次に、ローカル密度行列シミュレータです。このシミュレータもローカル環境で動作しますが、量子回路に対するノイズの影響をシミュレートできます。密度行列は状態ベクトルの 2 倍の大きさなので、効果的にシミュレートできる量子ビット数は、ローカル状態ベクトルシミュレータの半分になります。\n", 78 | "\n", 79 | "**推奨ユースケース :** 最大 6 量子ビットのノイズあり回路" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 3, 85 | "id": "c16bb05a-925e-4706-ad11-0580181173d9", 86 | "metadata": { 87 | "tags": [] 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "local_dm_simulator = BraketLocalBackend(name='braket_dm')" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "id": "8b8d88de-8bee-4298-8cc4-89f7b3280ff8", 97 | "metadata": {}, 98 | "source": [ 99 | "Braket オンデマンドシミュレータは、AWS のコンピューティングリソース上で動作し、ローカルシミュレータの機能に加え、いくつかの拡張機能を備えています。以下のコードで、利用可能な Braket のシミュレータをすべてリストアップすることができます。" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 4, 105 | "id": "a0d738da-fb1a-4430-926e-c41608b5b923", 106 | "metadata": { 107 | "tags": [] 108 | }, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "[BraketBackend[SV1], BraketBackend[TN1], BraketBackend[dm1]]" 114 | ] 115 | }, 116 | "execution_count": 4, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "from qiskit_braket_provider import AWSBraketProvider\n", 123 | "\n", 124 | "provider = AWSBraketProvider()\n", 125 | "\n", 126 | "provider.backends(statuses=[\"ONLINE\"], types=[\"SIMULATOR\"])" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "id": "4fd3c5ba-7c3f-42d5-bad4-8688df3f456a", 132 | "metadata": {}, 133 | "source": [ 134 | "オンデマンドシミュレータの 1 つめは SV1 です。これはフル状態ベクトルシミュレータで、ローカルシミュレータよりも大規模な回路のシミュレーションが可能です。また、タスクをバッチ処理して並列実行する機能とともに、変分量子アルゴリズムの adjoint 勾配計算などの応用テクニックも使用できます。\n", 135 | "\n", 136 | "**推奨ユースケース :** 最大 34 量子ビットのノイズなし変分アルゴリズム" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 5, 142 | "id": "d72c0fee-c643-46e6-b536-922b3d5e1b63", 143 | "metadata": { 144 | "tags": [] 145 | }, 146 | "outputs": [], 147 | "source": [ 148 | "aws_sv1 = provider.get_backend(\"SV1\")" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "id": "022f2518-cbb8-4679-8175-b0347fe41955", 154 | "metadata": {}, 155 | "source": [ 156 | "2 つめのオンデマンドシミュレータは DM1 です。これは密度行列シミュレータで、SV1 と同様に、より多くの量子ビットをシミュレートでき、バッチ実行も可能です。\n", 157 | "\n", 158 | "**推奨ユースケース :** 最大 17 量子ビットのノイズあり変分アルゴリズム" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 6, 164 | "id": "a1d6a663-7717-40ca-9bd1-4ea0e2591757", 165 | "metadata": { 166 | "tags": [] 167 | }, 168 | "outputs": [], 169 | "source": [ 170 | "aws_dm1 = provider.get_backend(\"dm1\")" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "id": "0b8e5316-46ea-4c81-b855-78d8d2784bc7", 176 | "metadata": {}, 177 | "source": [ 178 | "最後のオンデマンドシミュレータは TN1 です。これはテンソルネットワークシミュレータで、回路内の各ゲートをテンソルとして表現します。TN1 は、局所的なゲートやその他の特殊な構造を持つ回路では、より多くの量子ビットをシミュレートできますが、長距離のゲートや all-to-all のゲート構造を持つ回路に対しては、SV1 や DM1 よりも遅くなるのが普通です。\n", 179 | "\n", 180 | "**推奨ユースケース :** 局所的な接続性を持ち、最大 50 量子ビットのノイズなし回路" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "id": "3888f97e-fb68-428c-95ba-bff9b1e9fecc", 186 | "metadata": {}, 187 | "source": [ 188 | "**注意:** 各 AWS リソース (ファイル、CPU、QPUなど) は特定のリージョンにのみ存在し、そのリージョンからしかアクセスできない場合があります。例えば、TN1 は `eu-west-2`、 `us-east-1`、 `us-west-2` リージョンでのみ利用可能です。\n", 189 | "\n", 190 | "マネージドノートブックで実行している場合に AWS リージョンを変更するには、AWS コンソールの右上から新しいリージョンを選択し、Braket コンソールからノートブックを再起動または作成する必要があります。\n", 191 | "\n", 192 | "ローカル開発環境で実行している場合に AWS リージョンを変更するには、次のコードスニペットを実行します。\n", 193 | "```\n", 194 | "import os\n", 195 | "os.environ[\"AWS_REGION\"] = \"your-desired-region\"\n", 196 | "```" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 9, 202 | "id": "c3727ffa-36ea-4d8f-926a-5a7bed46cd57", 203 | "metadata": { 204 | "tags": [] 205 | }, 206 | "outputs": [], 207 | "source": [ 208 | "# TN1 にアクセスできるリージョンの 1 つに切り替えた場合は、次のコードのコメントを自由に解除できます。\n", 209 | "# aws_tn1 = provider.get_backend(\"TN1\")" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "id": "37f15848-db35-4a3b-8efb-2790f25f9708", 215 | "metadata": {}, 216 | "source": [ 217 | "### 量子処理ユニット (QPU)\n", 218 | "\n", 219 | "Amazon Braket では、多くのサードパーティ製量子ハードウェアデバイスへのアクセスも可能です。以下のコードは、現在オンラインの、サポートされている QPU を表示します。" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 10, 225 | "id": "891dbaac-f94f-41f9-947d-bed68342aca9", 226 | "metadata": { 227 | "tags": [] 228 | }, 229 | "outputs": [ 230 | { 231 | "data": { 232 | "text/plain": [ 233 | "[BraketBackend[Aspen-M-3], BraketBackend[Harmony]]" 234 | ] 235 | }, 236 | "execution_count": 10, 237 | "metadata": {}, 238 | "output_type": "execute_result" 239 | } 240 | ], 241 | "source": [ 242 | "provider.backends(statuses=[\"ONLINE\"], types=[\"QPU\"])" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "id": "906cccb3-4893-494a-8718-6b4b4a66621d", 248 | "metadata": {}, 249 | "source": [ 250 | "各量子コンピュータの詳細については、Braket ホームページの [Providers Overview](https://aws.amazon.com/braket/quantum-computers/)、または Braket コンソールの左側にある Devices タブから確認できます。\n", 251 | "現在、Qiskit-Braket プロバイダでサポートされているのは、ゲートベースのQPU (IonQ, OQC, Rigetti) のみです。" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "id": "e3af4dfd-d1ba-44aa-a913-18da11b3e520", 257 | "metadata": {}, 258 | "source": [ 259 | "## Braket デバイス上で回路を実行する\n", 260 | "\n", 261 | "Qiskit-Braket プロバイダで利用可能な量子デバイスについて説明したので、実際に使ってみましょう!今回の例では、Rigetti デバイスで 3 量子 GHZ 状態を作成しますが、以下のコメントアウトされたデバイスから自由に別の QPU を選択できます。" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": 11, 267 | "id": "7b870ef3-f2b8-47d4-b571-82ca22925fec", 268 | "metadata": { 269 | "tags": [] 270 | }, 271 | "outputs": [ 272 | { 273 | "name": "stdout", 274 | "output_type": "stream", 275 | "text": [ 276 | "BraketBackend[Aspen-M-3]\n" 277 | ] 278 | } 279 | ], 280 | "source": [ 281 | "qpu_backend = provider.get_backend(\"Aspen-M-3\")\n", 282 | "# qpu_backend = provider.get_backend(\"Lucy\")\n", 283 | "# qpu_backend = provider.get_backend(\"Harmony\")\n", 284 | "# qpu_backend = provider.get_backend(\"Aria 1\")\n", 285 | "\n", 286 | "print(qpu_backend)" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 12, 292 | "id": "dfa16813-80d8-407c-ac6d-ce7bb1982e17", 293 | "metadata": { 294 | "tags": [] 295 | }, 296 | "outputs": [ 297 | { 298 | "data": { 299 | "text/html": [ 300 | "
     ┌───┐          \n",
301 |        "q_0: ┤ H ├──■────■──\n",
302 |        "     └───┘┌─┴─┐  │  \n",
303 |        "q_1: ─────┤ X ├──┼──\n",
304 |        "          └───┘┌─┴─┐\n",
305 |        "q_2: ──────────┤ X ├\n",
306 |        "               └───┘
" 307 | ], 308 | "text/plain": [ 309 | " ┌───┐ \n", 310 | "q_0: ┤ H ├──■────■──\n", 311 | " └───┘┌─┴─┐ │ \n", 312 | "q_1: ─────┤ X ├──┼──\n", 313 | " └───┘┌─┴─┐\n", 314 | "q_2: ──────────┤ X ├\n", 315 | " └───┘" 316 | ] 317 | }, 318 | "execution_count": 12, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | } 322 | ], 323 | "source": [ 324 | "from qiskit import QuantumCircuit\n", 325 | "\n", 326 | "circuit = QuantumCircuit(3)\n", 327 | "circuit.h(0)\n", 328 | "circuit.cx(0, 1)\n", 329 | "circuit.cx(0, 2)\n", 330 | "circuit.draw()" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 13, 336 | "id": "e6237c66-f833-4554-8542-385c92500ace", 337 | "metadata": { 338 | "tags": [] 339 | }, 340 | "outputs": [], 341 | "source": [ 342 | "# run circuit\n", 343 | "qpu_task = qpu_backend.run(circuit, shots=10)" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "id": "b9bc9a23-a786-4fbd-8d90-d97a6e1ef972", 349 | "metadata": {}, 350 | "source": [ 351 | "実行したタスクには、それぞれ固有の ARN(Amazon Resource Name)が割り当てられ、これを保存しておくことで、タスク実行後にノートブックを閉じても、タスクのデータを取得することができます。" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": 14, 357 | "id": "c0952b4e-0d8c-4f74-859b-50ad53065854", 358 | "metadata": { 359 | "tags": [] 360 | }, 361 | "outputs": [ 362 | { 363 | "data": { 364 | "text/plain": [ 365 | "'arn:aws:braket:us-west-1:700863243650:quantum-task/1f41ab60-ed25-4352-8d2d-28b6772d94ee'" 366 | ] 367 | }, 368 | "execution_count": 14, 369 | "metadata": {}, 370 | "output_type": "execute_result" 371 | } 372 | ], 373 | "source": [ 374 | "task_id = qpu_task.job_id()\n", 375 | "task_id" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "id": "24514bc7-06d1-4a7a-9a20-af1b414fb388", 381 | "metadata": {}, 382 | "source": [ 383 | "**注意 :** Amazon Braket で「タスク (task)」と呼ばれるものを、Qiskit は「ジョブ (job)」という名称で使用しています。`.job_id()` を呼び出すことで、タスクの ARN にアクセスできるのはこのためです。\n", 384 | "\n", 385 | "一方で、Braket には「ハイブリッドジョブ (Hybrid Jobs)」と呼ばれる別の機能があります。この機能は今回のノートブックの範囲を超えていますが、[開発者ガイド](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html)で読むことができます。" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": 15, 391 | "id": "b5a183ef-c490-4771-a52b-9f31920115ff", 392 | "metadata": { 393 | "tags": [] 394 | }, 395 | "outputs": [], 396 | "source": [ 397 | "# タスクデータの取得\n", 398 | "retrieved_task = qpu_backend.retrieve_job(job_id=task_id)" 399 | ] 400 | }, 401 | { 402 | "cell_type": "markdown", 403 | "id": "5ba5ad23-cb76-4be4-99f4-c8c90b262470", 404 | "metadata": {}, 405 | "source": [ 406 | "その後、タスクが終了したかどうかステータスで確認できます。" 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": 22, 412 | "id": "e43a566b-3d67-47d9-bf10-273c02bd569a", 413 | "metadata": { 414 | "tags": [] 415 | }, 416 | "outputs": [ 417 | { 418 | "data": { 419 | "text/plain": [ 420 | "" 421 | ] 422 | }, 423 | "execution_count": 22, 424 | "metadata": {}, 425 | "output_type": "execute_result" 426 | } 427 | ], 428 | "source": [ 429 | "retrieved_task.status()" 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "id": "1f64ea6c-7c70-48a9-921a-924685252fdf", 435 | "metadata": {}, 436 | "source": [ 437 | "**注意:** デバイスによって、利用可能な時間帯は異なります。そのためタスクはすぐに実行されないかもしれませんが、キューに追加され、デバイスがオンラインに戻った時に実行されますので、ご安心ください。" 438 | ] 439 | }, 440 | { 441 | "cell_type": "markdown", 442 | "id": "a388fb50-73ea-473e-b67b-750ac85a3d71", 443 | "metadata": {}, 444 | "source": [ 445 | "タスクが終了したら、データを取得できます。" 446 | ] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": 23, 451 | "id": "45b16834-9e64-4d90-a460-bfb84f0f4425", 452 | "metadata": { 453 | "tags": [] 454 | }, 455 | "outputs": [], 456 | "source": [ 457 | "data = retrieved_task.result()" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": 24, 463 | "id": "d12f0cb5-71ac-41ae-8028-3436b4d6c198", 464 | "metadata": { 465 | "tags": [] 466 | }, 467 | "outputs": [ 468 | { 469 | "data": { 470 | "image/png": "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qcoVwlavXq1rr71WoaGhZzw3NDRU1157rb7++usKFwcAAFBTlSuE7du3T23btj3r89u0aaOffvqp3EUBAADUdOUKYS6XSwUFBWd9fkFBgVyuCu8HCwAAUGOVKyFFRUUpLS3trM9PS0vThRdeWO6iAAAAarpyhbCrrrpKK1as0M6dO8947s6dO7VixQpdffXVFa0NAACgxipXCEtISFBBQYHi4+N18ODBMs87dOiQbr75ZhUWFur+++8/5yIBAABqmnJt1tq9e3dNnDhRM2fOVExMjO677z7FxcXpoosukiTt3btXX375pebNm6cDBw5o0qRJ6t69+3kpHAAAoDor9475M2bMUJ06dfTyyy9r6tSpmjp1arHjxhi53W5NnjxZzz//fKUVCgAAUJOUO4Q5jqMXXnhBd911lxYsWKDVq1dr//79kqQWLVqob9++GjdunNq1a1fpxQIAANQUFb6Ad7t27ZjpAgAAqCA28QIAALCAEAYAAGABIQwAAMACQhgAAIAFhDAAAAALCGEAAAAWEMIAAAAsIIQBAABYQAgDAACwgBAGAABgASEMAADAAkIYAACABYQwAAAACwhhAAAAFhDCAAAALCCEAQAAWEAIAwAAsIAQBgAAYAEhDAAAwAJCGAAAgAWEMAAAAAsIYQAAABYQwgAAACwghAEAAFhACAMAALCAEAYAAGABIQwAAMACQhgAAIAFhDAAAAALCGEAAAAWEMIAAAAsIIQBAABYQAgDAACwgBAGAABgASEMAADAAkIYAACABYQwAAAACwhhAAAAFhDCAAAALCCEAQAAWEAIAwAAsIAQBgAAYAEhDAAAwAJCGAAAgAWEMAAAAAsIYQAAABYQwgAAACwghAEAAFhACAMAALCAEAYAAGABIQwAAMACQhgAAIAFhDAAAAALCGEAAAAWEMIAAAAsIIQBAABYEHAhbO/evZo5c6YGDRqkli1bKiQkRC1atNBNN92kdevW2S4PAACgUgRcCHv11Vf1yCOPaPv27Ro0aJAeffRRXXnllfroo4/Up08fvf/++7ZLBAAAOGdBtgs4Vc+ePZWcnKx+/foVa1+1apUGDBig+++/XyNGjFBoaKilCgEAAM5dwM2E3XjjjSUCmCRdddVViouL05EjR/T9999bqAwAAKDyBFwIO53g4GBJUlBQwE3gAQAAlEu1STO7d+/W8uXLdcEF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qkGDBmnYsGG64oorir2GFL1V/euvv2revHnq2rWr4uLiLFYOWxgzFVQ1O2GgshTtXv7GG2+UOHbyvmFF+7HccMMNpkOHDmbnzp1VViMCx48//mgaNGhgnnjiCX+b1+stsV9PXl6e+fTTT03btm1NZGSkWb16dVWXigCRlpZmHMcxl19+uRk4cKB/v8EGDRqYwYMHm1mzZpkff/yx2H1WrVplHMcxffv2tVQ1bGLMVBxzg9XMf/zHf+iyyy7T3XffrYceekjffPONjh8/Lunfn2orLCyUy+WSx+NRSEiIjh8/rlatWtksG5YYY9SwYUP/FhNF2wmcOnsaEhKiYcOG6ZVXXtGRI0e0atUqazXDru+//16SdOuttyoxMVGbN2/WSy+9pIsvvliJiYmaOHGirrnmGt166636+9//riNHjiglJUWSNHnyZJulwxLGzDmwHAJRAR9++KH/Ug+XX365ee6550xSUpLZuXOnyc3N9Z/39ttvm6ZNm5p7773XYrWw7YorrjBhYWFm2bJlJY4VzZ4WzYwdOnTItGnTxsTHx1dpjQgcc+fONY7jlDpeUlJSzCOPPGKio6P9sx0dOnQwLVq0MBEREVVfLAICY6biWBNWTZhT1nMdPnxYL774ohYvXqzMzEw1bdpUl112maKiolSvXj3l5uZq8eLFatOmjZYsWaKOHTtarB42FI2ZlJQU3Xjjjdq3b58efvhhjR49Wl26dFGdOnX85xZt6LtmzRrFx8crPj5es2bNslg9bDDGaN26dVq8eLESEhLUrl07f/vJrz/Hjx/Xl19+qQ8++EBLliyRx+NRQkKCXn31VVulwxLGzLkhhFUjRYN6z549ioqKksvlUlpampYuXark5GT9+OOPyszMlCQ1atRIsbGxmj17ti699FLLlcMmr9ert99+W5MnT9b+/fsVExOjQYMGqU+fPoqJiVGnTp3kcrm0d+9ePfbYY/rggw+0bt06de/e3XbpsCQ7O1shISEKCQkpcezUP64PPvig5syZo2+++UaxsbFVWCUCCWOmYghh1UBhYaG+/vprvfnmm0pPT5fjOKpXr5569OihW265Rd26dZMxRpmZmcrNzdX27dvVqVMnRUdHKygoiE9FQpJ04MABvfbaa1q8eLHS09NVr149XXjhhWrQoIEiIyO1efNmHThwQOPHj9ecOXNsl4sAVvSasm3bNo0aNUpZWVnKyMiwXRYCGGOmdISwamD69Ol67rnndOzYMV188cVyu93asmWL/3hMTIweeOABxcfHc7kQlGBOulhubm6uMjIytH79en399ddat26dNm/erKZNmyo6Olp33323br/9dtWvX9922agGli5dquHDh+uxxx7TtGnTbJeDaoAxUxwhLMDt2LFDnTt3Vvfu3bVo0SKFhISoefPm2r9/vz755BN98MEHSk5OliTFxcVp2rRpuvzyy+0WjYDn8/l0/PhxhYSEKCsrS/v37+dta/id7ez5zz//rM8//1zXX3+9IiMjq6AyBCrGTMUQwgLcU089pblz5+rdd9/VgAEDJJUc7N9//72mT5+uxYsXq1WrVnrnnXf0m9/8xlbJsCw3N1e7d+9Wy5YtVbdu3WLHfD6fHMcpdpHuk8fSyZv/ovY43Zg5k9p6zb/ajjFTOXi1DXCbNm1SgwYN1L59e0nyX6bI/P912iSpc+fOWrRokV566SWlp6frtddes1kyLJs1a5Zuv/12zZw5U0lJSdq3b59/rLhcLv/4OTmAHThwwL+/HGqf042ZshSNGf6Y1k6MmcrBTFiAe/755/XUU08pLS1NMTExpZ5z8h/T+Ph4rV+/XklJSWrbtm1VlooAcdFFF2nfvn1yu92KiIhQnz59NGjQIF1xxRVq27ZtiUsX5eTk6Omnn9ahQ4f0+uuvE8RqoXMZM/Pnz+ePai3EmKkcXO4+wBVdU+u2227TjBkzdOWVV5b6EeCi6d2OHTvqs88+U3Z2dlWXigCQnp6urKws9e7dW7feeqv++c9/as2aNVq6dKlatmyp/v3769prr1W3bt104YUXqmHDhkpLS9P8+fPVv39/AlgtdK5jhj+mtQ9jpvIQwgJcr169NGnSJL3yyit68MEHlZCQoPj4eDVv3tx/juM4crvdOnLkiPbs2aP69eurS5cuFquGLenp6Tp+/LgGDRqkhIQE/fa3v9WWLVu0Zs0arVixQv/4xz/0zjvvKCYmRtdcc42GDBmiL7/8Uh6PRxMmTLBdPixgzKC8GDOVh7cjq4m5c+fq5Zdf1vbt2xUVFaWRI0dq6NChio6OltvtVsOGDfXqq69q5syZeuCBBzRjxgzbJcOC//7v/9Ytt9yi9957T7fccou/vaCgQLt27dK3336rVatW+Tf3DQ4OljFGoaGhOnz4sMXKYQtjBuXFmKk8hLBqwhijrVu3av78+Xrvvfe0Z88eSVKzZs0UHBysn376ST6fT6NHj9a0adN00UUXWa4YNhhjtHnzZtWpU0dt2rQp9WPjOTk5Sk9P15YtW7RgwQL985//1IMPPqjZs2dbqho2MWZQXoyZykMIq4ZycnKUkpKijz/+WPv27dMvv/yi8PBw3XLLLbrpppuKXRMQKFLaC+VDDz2k1157TRs2bFC3bt0sVYZAxZhBeTFmyocQVs0VFBQoODjYdhmoRor2Atu5c6duuOEGHTlyRLt377ZdFgIYYwblxZg5O3wUqpojgKG8ij4BuXfvXhUUFOiBBx6wXBECHWMG5cWYOTvMhAG1lDFGe/bsUWRkJNeKxFlhzKC8GDOnRwgDAACwgLcjAQAALCCEAQAAWEAIAwAAsIAQBgAAYAEhDAAAwAJCGAAAgAWEMAAAAAsIYQAAABYQwgAAACz4Pw4bks8N8ywiAAAAAElFTkSuQmCC", 471 | "text/plain": [ 472 | "
" 473 | ] 474 | }, 475 | "execution_count": 24, 476 | "metadata": {}, 477 | "output_type": "execute_result" 478 | } 479 | ], 480 | "source": [ 481 | "from qiskit.visualization import plot_histogram\n", 482 | "plot_histogram(data.get_counts())" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "id": "20ce9b2f-83d1-4f4b-9ac4-7e1f2c351dba", 488 | "metadata": {}, 489 | "source": [ 490 | "## Braket デバイス上でアルゴリズムを実行する\n", 491 | "\n", 492 | "さらに、Qiskit-Braket provider を使用して、Braket バックエンド上で組み込みの Qiskit アルゴリズムを実行できます。例えば、水素の基底状態を見つけるために VQE アルゴリズムを実行できます。この問題は少ない量子ビットしか必要としない基底で表現でき、素早く実行できるので、ローカルシミュレータを使用します。" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 26, 498 | "id": "45b133dd-d37c-4f53-8385-e8715cdfcccb", 499 | "metadata": { 500 | "tags": [] 501 | }, 502 | "outputs": [], 503 | "source": [ 504 | "from qiskit.opflow import (\n", 505 | " I,\n", 506 | " X,\n", 507 | " Z,\n", 508 | ")\n", 509 | "\n", 510 | "# H2 のハミルトニアン演算子を Pauli スピン演算子で定義します。\n", 511 | "H2_op = (\n", 512 | " (-1.052373245772859 * I ^ I)\n", 513 | " + (0.39793742484318045 * I ^ Z)\n", 514 | " + (-0.39793742484318045 * Z ^ I)\n", 515 | " + (-0.01128010425623538 * Z ^ Z)\n", 516 | " + (0.18093119978423156 * X ^ X)\n", 517 | ")" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": 27, 523 | "id": "9a4af5ae-b7bc-40c2-b375-176ff54d8cda", 524 | "metadata": { 525 | "tags": [] 526 | }, 527 | "outputs": [ 528 | { 529 | "name": "stdout", 530 | "output_type": "stream", 531 | "text": [ 532 | "{ 'aux_operator_eigenvalues': None,\n", 533 | " 'cost_function_evals': 9,\n", 534 | " 'eigenstate': { '00': 0.12103072956898178,\n", 535 | " '01': 0.11692679333668567,\n", 536 | " '10': 0.10825317547305482,\n", 537 | " '11': 0.9797759629119301},\n", 538 | " 'eigenvalue': (-1.0889057236530086+0j),\n", 539 | " 'optimal_circuit': None,\n", 540 | " 'optimal_parameters': { ParameterVectorElement(θ[3]): -5.755436545071434,\n", 541 | " ParameterVectorElement(θ[1]): -0.06350247974205825,\n", 542 | " ParameterVectorElement(θ[7]): -5.525501547721888,\n", 543 | " ParameterVectorElement(θ[4]): -5.425306283034111,\n", 544 | " ParameterVectorElement(θ[0]): -2.9712537272548736,\n", 545 | " ParameterVectorElement(θ[6]): 4.055161926547246,\n", 546 | " ParameterVectorElement(θ[5]): -4.2635679526293035,\n", 547 | " ParameterVectorElement(θ[2]): -3.5371159105090197},\n", 548 | " 'optimal_point': array([-2.97125373, -0.06350248, -3.53711591, -5.75543655, -5.42530628,\n", 549 | " -4.26356795, 4.05516193, -5.52550155]),\n", 550 | " 'optimal_value': -1.0889057236530086,\n", 551 | " 'optimizer_evals': None,\n", 552 | " 'optimizer_result': None,\n", 553 | " 'optimizer_time': 0.8830254077911377}\n" 554 | ] 555 | } 556 | ], 557 | "source": [ 558 | "# ライブラリのインポート\n", 559 | "from qiskit.utils import QuantumInstance\n", 560 | "from qiskit.circuit.library import TwoLocal\n", 561 | "from qiskit.algorithms.optimizers import SLSQP\n", 562 | "from qiskit.algorithms import VQE\n", 563 | "\n", 564 | "# Braket バックエンドで `QuantumInstance` を定義します。\n", 565 | "qi = QuantumInstance(local_simulator, seed_transpiler=42, seed_simulator=42)\n", 566 | "\n", 567 | "# VQE の設定\n", 568 | "ansatz = TwoLocal(rotation_blocks=\"ry\", entanglement_blocks=\"cz\")\n", 569 | "slsqp = SLSQP(maxiter=1)\n", 570 | "vqe = VQE(ansatz, optimizer=slsqp, quantum_instance=qi)\n", 571 | "\n", 572 | "# 基底状態を見つけます。\n", 573 | "result = vqe.compute_minimum_eigenvalue(H2_op)\n", 574 | "print(result)" 575 | ] 576 | }, 577 | { 578 | "cell_type": "markdown", 579 | "id": "db9fd813-d906-4b2e-a9e3-1bef49119f40", 580 | "metadata": {}, 581 | "source": [ 582 | "## 今後のアクション\n", 583 | "\n", 584 | "可能性は無限大です!Qiskit-Braket provider はまだ新しく実験的なものなので、バグに遭遇した場合や新機能をサポートしたい場合は、[GitHub に issue を提出](https://github.com/qiskit-community/qiskit-braket-provider/issues)し、feature ブランチを作って開発に参加してみてください!" 585 | ] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "execution_count": 28, 590 | "id": "b6c4c957-8621-4a87-abcc-cf52985b7ba1", 591 | "metadata": { 592 | "tags": [] 593 | }, 594 | "outputs": [ 595 | { 596 | "name": "stdout", 597 | "output_type": "stream", 598 | "text": [ 599 | "Task Summary\n", 600 | "{'arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3': {'shots': 10, 'tasks': {'COMPLETED': 1}}}\n", 601 | "Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).\n", 602 | "Estimated cost to run this example: 0.30 USD\n" 603 | ] 604 | } 605 | ], 606 | "source": [ 607 | "print(\"Task Summary\")\n", 608 | "print(t.quantum_tasks_statistics())\n", 609 | "print('Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).')\n", 610 | "print(f\"Estimated cost to run this example: {t.qpu_tasks_cost() + t.simulator_tasks_cost():.2f} USD\")" 611 | ] 612 | }, 613 | { 614 | "cell_type": "code", 615 | "execution_count": null, 616 | "id": "91adb2cf-d9ba-4bca-b4e8-11cc3dcbcff6", 617 | "metadata": {}, 618 | "outputs": [], 619 | "source": [] 620 | } 621 | ], 622 | "metadata": { 623 | "kernelspec": { 624 | "display_name": "conda_braket", 625 | "language": "python", 626 | "name": "conda_braket" 627 | }, 628 | "language_info": { 629 | "codemirror_mode": { 630 | "name": "ipython", 631 | "version": 3 632 | }, 633 | "file_extension": ".py", 634 | "mimetype": "text/x-python", 635 | "name": "python", 636 | "nbconvert_exporter": "python", 637 | "pygments_lexer": "ipython3", 638 | "version": "3.10.11" 639 | } 640 | }, 641 | "nbformat": 4, 642 | "nbformat_minor": 5 643 | } 644 | -------------------------------------------------------------------------------- /workshop/pennylane/3_Quantum_chemistry_with_VQE.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# VQEによる量子化学計算" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "このチュートリアルでは、Amazon Braket で PennyLane を使用して量子化学の重要な問題、すなわち分子の基底状態エネルギーを見つける方法を説明します。この問題は、変分量子固有値ソルバー (Variational Quantum Eigensolver; VQE) アルゴリズムを実装することにより、NISQ ハードウェアを利用して解くことができます。量子化学と VQE の詳細については、[Braket VQE ノートブック](../Hybrid_quantum_algorithms/vqe_Chemistry/vqe_Chemistry_braket.ipynb) や [PennyLane チュートリアル](https://pennylane.ai/qml/demos/tutorial_qubit_rotation.html) を参考にして下さい。" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "
\n", 22 | "注: このノートブックの実行には pennylane>=0.18 以上と amazon-braket-pennylane-plugin>=1.5.0 が必要です。\n", 23 | "
" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## 量子化学から量子回路へ" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "まず最初のステップは、量子化学の問題を量子コンピュータで扱えるよう変換することです。PennyLane では ``qchem`` パッケージを使います。ローカルマシン上で実行している場合、``qchem`` パッケージは [これら](https://pennylane.readthedocs.io/en/stable/introduction/chemistry.html) の指示に従って別途インストールする必要があります。" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 1, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "import pennylane as qml\n", 47 | "from pennylane import qchem\n", 48 | "from pennylane import numpy as np" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "入力化学データは、多くの場合、分子に関する詳細を含むジオメトリファイルの形式で提供されます。ここで、[h2.xyz](./qchem/h2.xyz) ファイルに保存された $\\mathrm {H} _2$ の原子構造を考えます。量子ビットハミルトニアンは ``qchem`` パッケージを使って構成されています。" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 2, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | " (-0.24274280513140456) [Z2]\n", 68 | "+ (-0.24274280513140456) [Z3]\n", 69 | "+ (-0.04207897647782281) [I0]\n", 70 | "+ (0.1777128746513994) [Z1]\n", 71 | "+ (0.17771287465139946) [Z0]\n", 72 | "+ (0.12293305056183798) [Z0 Z2]\n", 73 | "+ (0.12293305056183798) [Z1 Z3]\n", 74 | "+ (0.16768319457718958) [Z0 Z3]\n", 75 | "+ (0.16768319457718958) [Z1 Z2]\n", 76 | "+ (0.17059738328801055) [Z0 Z1]\n", 77 | "+ (0.17627640804319586) [Z2 Z3]\n", 78 | "+ (-0.04475014401535161) [Y0 Y1 X2 X3]\n", 79 | "+ (-0.04475014401535161) [X0 X1 Y2 Y3]\n", 80 | "+ (0.04475014401535161) [Y0 X1 X2 Y3]\n", 81 | "+ (0.04475014401535161) [X0 Y1 Y2 X3]\n" 82 | ] 83 | } 84 | ], 85 | "source": [ 86 | "symbols, coordinates = qchem.read_structure('qchem/h2.xyz')\n", 87 | "h, qubits = qchem.molecular_hamiltonian(symbols, coordinates, name=\"h2\")\n", 88 | "print(h)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "VQE アルゴリズムでは、変分量子回路上の上記のハミルトニアンの期待値を測定することにより、$\\mathrm {H} _2$ 分子のエネルギーを計算します。我々の目的は、ハミルトニアンの期待値が最小になるように回路のパラメータを訓練し、それによって分子の基底状態エネルギーを見つけることです。\n", 96 | "\n", 97 | "このチュートリアルでは、トータルスピンも計算します。そのために、``qchem`` パッケージを使ってトータルスピン演算子 $S^2$ を構築します。" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 3, 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "name": "stdout", 107 | "output_type": "stream", 108 | "text": [ 109 | " (0.375) [Z1]\n", 110 | "+ (0.375) [Z0]\n", 111 | "+ (0.375) [Z2]\n", 112 | "+ (0.375) [Z3]\n", 113 | "+ (0.75) [I0]\n", 114 | "+ (-0.375) [Z0 Z1]\n", 115 | "+ (-0.375) [Z2 Z3]\n", 116 | "+ (-0.125) [Z0 Z3]\n", 117 | "+ (-0.125) [Z1 Z2]\n", 118 | "+ (0.125) [Z0 Z2]\n", 119 | "+ (0.125) [Z1 Z3]\n", 120 | "+ (-0.125) [Y0 X1 X2 Y3]\n", 121 | "+ (-0.125) [X0 Y1 Y2 X3]\n", 122 | "+ (0.125) [Y0 X1 Y2 X3]\n", 123 | "+ (0.125) [Y0 Y1 X2 X3]\n", 124 | "+ (0.125) [Y0 Y1 Y2 Y3]\n", 125 | "+ (0.125) [X0 X1 X2 X3]\n", 126 | "+ (0.125) [X0 X1 Y2 Y3]\n", 127 | "+ (0.125) [X0 Y1 X2 Y3]\n" 128 | ] 129 | } 130 | ], 131 | "source": [ 132 | "electrons = 2 # Molecular hydrogen has two electrons\n", 133 | "\n", 134 | "S2 = qchem.spin2(electrons, qubits)\n", 135 | "print(S2)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "## Ansatz 回路の定義" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "ここで、ハミルトニアンの基底状態を準備するために訓練される ansatz 回路を設定します。最初のステップは、ローカルの Braket デバイスを読み込むことです。\n", 150 | "\n", 151 | "このチュートリアルでは、[Delgado et al. (2020)](https://arxiv.org/abs/2106.13840) の [`AllSinglesDoubles`](https://pennylane.readthedocs.io/en/stable/code/api/pennylane.templates.subroutines.UCCSD.html) ansatz という化学インスパイアドな回路を使います。これを使用するには、量子化学の観点から追加の入力項目をいくつか定義する必要があります。" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 7, 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "# Hartree-Fock state\n", 161 | "hf_state = qchem.hf_state(electrons, qubits)\n", 162 | "# generate single- and double-excitations\n", 163 | "singles, doubles = qchem.excitations(electrons, qubits)" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "
\n", 171 | "注: さまざまな ansatz とテンプレートが利用可能で、違うものを選ぶと、回路の深さや学習可能なパラメータ数が異なります。\n", 172 | "
" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "この ansatz 回路は簡単に定義できます:" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 8, 185 | "metadata": {}, 186 | "outputs": [], 187 | "source": [ 188 | "def circuit(params, wires):\n", 189 | " qml.templates.AllSinglesDoubles(params, wires, hf_state, singles, doubles)" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "出力の測定はまだ定義されていないことに注意してください。これは次のステップで行います。" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "## エネルギーとトータルスピンの測定" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "回路を実行するために、デバイスをインスタンス化します。Braket Local Simulator を使います。" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [ 219 | "dev = qml.device(\"braket.local.qubit\", wires=qubits)" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": {}, 225 | "source": [ 226 | "先に説明したように、$\\mathrm {H} _2$ のエネルギーに対応する量子ビットハミルトニアンの期待値を最小化したいと考えています。このハミルトニアンとトータルスピン $\\hat {S} ^2$ 演算子の期待値は、以下を使用して定義できます。" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 9, 232 | "metadata": {}, 233 | "outputs": [], 234 | "source": [ 235 | "wires = dev.wires.tolist()\n", 236 | "\n", 237 | "@qml.qnode(dev)\n", 238 | "def energy_expval(params):\n", 239 | " circuit(params, wires)\n", 240 | " return qml.expval(h)\n", 241 | "\n", 242 | "@qml.qnode(dev)\n", 243 | "def S2_expval(params):\n", 244 | " circuit(params, wires)\n", 245 | " return qml.expval(S2)" 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "metadata": {}, 251 | "source": [ 252 | "ここで、`dev` は `shots` パラメータを持たないことに注意してください。これは、1回の評価でハミルトニアンの厳密な期待値を計算できることを意味します。\n", 253 | "\n", 254 | "次に、ランダムな値をいくつか初期化し、エネルギーとスピンを評価しましょう。準備された状態のトータルスピン$S$は、$S=-\\frac {1} {2} +\\sqrt {\\frac {1} {4} +\\langle\\hat {S} ^2\\rangle}$ を用いて、期待値 $\\langle \\hat {S}^2 \\rangle$ から得ることができます。$S$ を計算する関数はこのように定義することができます:" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": 10, 260 | "metadata": {}, 261 | "outputs": [], 262 | "source": [ 263 | "def spin(params):\n", 264 | " return -0.5 + np.sqrt(1 / 4 + S2_expval(params))" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 11, 270 | "metadata": {}, 271 | "outputs": [], 272 | "source": [ 273 | "np.random.seed(1967)\n", 274 | "params = np.random.normal(0, np.pi, len(singles) + len(doubles))" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "エネルギーとトータルスピンは、" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": 12, 287 | "metadata": {}, 288 | "outputs": [ 289 | { 290 | "name": "stdout", 291 | "output_type": "stream", 292 | "text": [ 293 | "Energy: -0.27304966436310224\n", 294 | "Spin: 0.11000908988780533\n" 295 | ] 296 | } 297 | ], 298 | "source": [ 299 | "print(\"Energy:\", energy_expval(params))\n", 300 | "print(\"Spin: \", spin(params))" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "ランダムなパラメータを選んだので、測定されたエネルギーは基底状態エネルギーに対応しておらず、準備状態はトータルスピン演算子の固有状態ではありません。ここで、最小エネルギーを見つけるためにパラメータをトレーニングする必要があります。" 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "metadata": {}, 313 | "source": [ 314 | "## エネルギー最小化" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "エネルギーは、オプティマイザーを選択し、標準の最適化ループを実行することで最小化できます。" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 13, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "opt = qml.GradientDescentOptimizer(stepsize=0.4)" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": {}, 337 | "outputs": [], 338 | "source": [ 339 | "iterations = 40" 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": null, 345 | "metadata": {}, 346 | "outputs": [], 347 | "source": [ 348 | "def run_vqe(energy_expval, spin, opt, initial_params, iterations):\n", 349 | " energies = []\n", 350 | " spins = []\n", 351 | " params = initial_params\n", 352 | "\n", 353 | " for i in range(iterations):\n", 354 | " params = opt.step(energy_expval, params)\n", 355 | " \n", 356 | " e = energy_expval(params)\n", 357 | " s = spin(params)\n", 358 | " \n", 359 | " energies.append(e)\n", 360 | " spins.append(s)\n", 361 | " \n", 362 | " if (i + 1) % 5 == 0:\n", 363 | " print(f\"Completed iteration {i + 1}\")\n", 364 | " print(\"Energy:\", e)\n", 365 | " print(\"Total spin:\", s)\n", 366 | " print(\"----------------\")\n", 367 | " \n", 368 | " print(f\"Optimized energy: {e} Ha\")\n", 369 | " print(f\"Corresponding total spin: {s}\")\n", 370 | " return energies, spins" 371 | ] 372 | }, 373 | { 374 | "cell_type": "code", 375 | "execution_count": 14, 376 | "metadata": {}, 377 | "outputs": [ 378 | { 379 | "name": "stdout", 380 | "output_type": "stream", 381 | "text": [ 382 | "Completed iteration 5\n", 383 | "Energy: -0.6355679018250266\n", 384 | "Total spin: 0.11730536055750063\n", 385 | "----------------\n", 386 | "Completed iteration 10\n", 387 | "Energy: -0.9411439477019683\n", 388 | "Total spin: 0.05338891122286116\n", 389 | "----------------\n", 390 | "Completed iteration 15\n", 391 | "Energy: -1.0953476071202999\n", 392 | "Total spin: 0.012154011361553807\n", 393 | "----------------\n", 394 | "Completed iteration 20\n", 395 | "Energy: -1.1289360208519634\n", 396 | "Total spin: 0.0022417391335066705\n", 397 | "----------------\n", 398 | "Completed iteration 25\n", 399 | "Energy: -1.1349263900521251\n", 400 | "Total spin: 0.00039974850346669033\n", 401 | "----------------\n", 402 | "Completed iteration 30\n", 403 | "Energy: -1.1359701193564353\n", 404 | "Total spin: 7.088996239612566e-05\n", 405 | "----------------\n", 406 | "Completed iteration 35\n", 407 | "Energy: -1.1361513824252214\n", 408 | "Total spin: 1.2559325300198765e-05\n", 409 | "----------------\n", 410 | "Completed iteration 40\n", 411 | "Energy: -1.136182845906552\n", 412 | "Total spin: 2.224718140930726e-06\n", 413 | "----------------\n", 414 | "Optimized energy: -1.136182845906552 Ha\n", 415 | "Corresponding total spin: 2.224718140930726e-06\n" 416 | ] 417 | } 418 | ], 419 | "source": [ 420 | "energies, spins = run_vqe(energy_expval, spin, opt, params, iterations)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "水素分子の基底状態エネルギーの正確な値は ``-1.136189454088`` Hartrees (Ha) として理論的に計算されています。最適化されたエネルギーの誤差は、Hartree の $10^ {-5} $ 未満であることに注意してください。さらに、最適化された状態は、$\\mathrm {H} _2$分子の基底状態に予想される固有値$S=0$を持つトータルスピン演算子の固有状態です。したがって、上記の結果は非常に有望に見えます!反復回数を増やすと、理論値にさらに近づきます。\n", 428 | "\n", 429 | "最適化中に 2 つの量がどのように変化したかを可視化してみましょう。" 430 | ] 431 | }, 432 | { 433 | "cell_type": "code", 434 | "execution_count": 15, 435 | "metadata": {}, 436 | "outputs": [ 437 | { 438 | "data": { 439 | "image/png": "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\n", 440 | "text/plain": [ 441 | "
" 442 | ] 443 | }, 444 | "metadata": { 445 | "needs_background": "light" 446 | }, 447 | "output_type": "display_data" 448 | } 449 | ], 450 | "source": [ 451 | "import matplotlib.pyplot as plt\n", 452 | "from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n", 453 | "\n", 454 | "theory_energy = -1.136189454088\n", 455 | "theory_spin = 0\n", 456 | "\n", 457 | "plt.hlines(theory_energy, 0, 39, linestyles=\"dashed\", colors=\"black\")\n", 458 | "plt.plot(energies)\n", 459 | "plt.xlabel(\"Steps\")\n", 460 | "plt.ylabel(\"Energy\")\n", 461 | "\n", 462 | "axs = plt.gca()\n", 463 | "\n", 464 | "inset = inset_axes(axs, width=\"50%\", height=\"50%\", borderpad=1)\n", 465 | "inset.hlines(theory_spin, 0, 39, linestyles=\"dashed\", colors=\"black\")\n", 466 | "inset.plot(spins, \"r\")\n", 467 | "inset.set_xlabel(\"Steps\")\n", 468 | "inset.set_ylabel(\"Total spin\");" 469 | ] 470 | }, 471 | { 472 | "cell_type": "markdown", 473 | "metadata": {}, 474 | "source": [ 475 | "ここまでで、Pennylane/Braket パイプラインを使用して、分子の基底状態エネルギーを効率的に見つける方法を学びました!" 476 | ] 477 | }, 478 | { 479 | "cell_type": "markdown", 480 | "metadata": {}, 481 | "source": [ 482 | "## `shots>0` での VQE の実行\n", 483 | "\n", 484 | "上記の例では、ハミルトニアンの厳密な期待値計算を、それぞれ1回の評価で行うことが可能でした。これはシミュレータが状態にアクセス可能であるためで、QPU のように測定により期待値を計算するデバイスの場合は不可能です。\n", 485 | "\n", 486 | "電子ハミルトニアン ``h`` の期待値を有限回の測定から求めたいとします。このハミルトニアンは、パウリ作用素のテンソル積である15の個々のオブザーバブルから構成されます。" 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": null, 492 | "metadata": {}, 493 | "outputs": [], 494 | "source": [ 495 | "print(\"Number of Pauli terms in h:\", len(h.ops))" 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": {}, 501 | "source": [ 502 | "期待値を測定する簡単なアプローチは、回路を15回実装し、毎回ハミルトニアン ``h`` の一部を形成するパウリ項の1つを測定することです。しかし、もっと効率的な方法があるかもしれません。パウリ項は、単一の回路で同時に測定できるグループ(PennyLane の [グループ化](https://pennylane.readthedocs.io/en/stable/code/qml_grouping.html) モジュールを参照)に分けることができます。各グループの要素は、量子ビットごとに交換可能なオブザーバブルとして知られています。ハミルトニアン ``h`` は5つのグループに分けることができます:" 503 | ] 504 | }, 505 | { 506 | "cell_type": "code", 507 | "execution_count": null, 508 | "metadata": {}, 509 | "outputs": [], 510 | "source": [ 511 | "groups, coeffs = qml.grouping.group_observables(h.ops, h.coeffs)\n", 512 | "print(\"Number of qubit-wise commuting groups:\", len(groups))" 513 | ] 514 | }, 515 | { 516 | "cell_type": "markdown", 517 | "metadata": {}, 518 | "source": [ 519 | "実際には、これは15の別々の回路を実行する代わりに、5つを実行するだけで済むことを意味します。この節約は、ハミルトニアンのパウリ項の数が増えるにつれて、さらに顕著になります。例えば、より大きな分子または異なる化学的基底集合に切り替えると、量子ビット数と項数の両方が増加する可能性があります。\n", 520 | "\n", 521 | "幸い、PennyLane/Braket パイプラインには、デバイスの実行回数を最小限に抑えるためにオブザーバブルを事前にグループ化するための機能が組み込まれており、リモートデバイスを使用するときの実行時間とシミュレーション料金の両方を節約できます。このチュートリアルの残りの部分では、最適化されたオブザーバブルのグループ化を使用します。" 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "
" 529 | ] 530 | }, 531 | { 532 | "cell_type": "markdown", 533 | "metadata": {}, 534 | "source": [ 535 | "グループ化の恩恵を受けるためには、PennyLane が各ハミルトニアンを量子ビットごとの可換なグループに分割するよう指示する必要があります。そのため、グルーピングを計算し、ハミルトニアンと保存します。デバイスは、回路を生成する際にこの情報を使います。" 536 | ] 537 | }, 538 | { 539 | "cell_type": "code", 540 | "execution_count": null, 541 | "metadata": {}, 542 | "outputs": [], 543 | "source": [ 544 | "h.compute_grouping()\n", 545 | "S2.compute_grouping()" 546 | ] 547 | }, 548 | { 549 | "cell_type": "markdown", 550 | "metadata": {}, 551 | "source": [ 552 | "次に、非ゼロの `shots` を指定してデバイスをインスタンス化します。" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": null, 558 | "metadata": {}, 559 | "outputs": [], 560 | "source": [ 561 | "dev = qml.device(\"braket.local.qubit\", wires=qubits, shots=1000)" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "metadata": {}, 567 | "source": [ 568 | "コスト関数を再定義します。" 569 | ] 570 | }, 571 | { 572 | "cell_type": "code", 573 | "execution_count": null, 574 | "metadata": {}, 575 | "outputs": [], 576 | "source": [ 577 | "wires = dev.wires.tolist()\n", 578 | "\n", 579 | "@qml.qnode(dev)\n", 580 | "def energy_expval(params):\n", 581 | " circuit(params, wires)\n", 582 | " return qml.expval(h)\n", 583 | "\n", 584 | "@qml.qnode(dev)\n", 585 | "def S2_expval(params):\n", 586 | " circuit(params, wires)\n", 587 | " return qml.expval(S2)\n", 588 | "\n", 589 | "def spin(params):\n", 590 | " return -0.5 + np.sqrt(1 / 4 + S2_expval(params))" 591 | ] 592 | }, 593 | { 594 | "cell_type": "markdown", 595 | "metadata": {}, 596 | "source": [ 597 | "最後に、VQE の実験を行い期待値を推定します。" 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": null, 603 | "metadata": {}, 604 | "outputs": [], 605 | "source": [ 606 | "energies, spins = run_vqe(energy_expval, spin, opt, params, iterations)" 607 | ] 608 | }, 609 | { 610 | "cell_type": "markdown", 611 | "metadata": {}, 612 | "source": [ 613 | "厳密な計算と非常に近い値が得られました!この実験では Local Simulator を使いましたが、同じことが QPU やショット数を非ゼロとした他のシミュレータでも実行できます。\n", 614 | "\n", 615 | "
\n", 616 | "次のステップは? qchem フォルダには、水素分子の異なる原子間距離を表す追加の分子構造ファイルが含まれています。原子間距離の 1 つを選択し、基底状態のエネルギーを求めましょう。原子間距離によって基底状態のエネルギーはどのように変化するでしょう? \n", 617 | "
" 618 | ] 619 | } 620 | ], 621 | "metadata": { 622 | "kernelspec": { 623 | "display_name": "conda_braket", 624 | "language": "python", 625 | "name": "conda_braket" 626 | }, 627 | "language_info": { 628 | "codemirror_mode": { 629 | "name": "ipython", 630 | "version": 3 631 | }, 632 | "file_extension": ".py", 633 | "mimetype": "text/x-python", 634 | "name": "python", 635 | "nbconvert_exporter": "python", 636 | "pygments_lexer": "ipython3", 637 | "version": "3.7.13" 638 | } 639 | }, 640 | "nbformat": 4, 641 | "nbformat_minor": 4 642 | } 643 | --------------------------------------------------------------------------------