タイトルの通り。こちらを参考にした。
IBM(International Business Machines Corporation)が提供しているQiskitという量子コンピュータを扱うためのライブラリや環境構築について。
まずは環境をvenvで用意してやる。
$ python3 --version
Python 3.11.6
$ python3 -m venv qiskit
$ source qiskit/bin/activate.fish
ここで私はmacのターミナルにfishを使っているので、activate.fishを使っているが、そうでない人はその環境に合わせたものを。
環境に入ったら、
$ pip install qiskit
$ pip install qiskit-ibm-runtime
$ pip install qiskit[visualization]
$ pip install jupyter
$ jupyter notebook
でJupyterNotebookを立ち上げる。立ち上げたら新規作成で hello_quantum.ipynb を作成する。
IBM 量子コンピュータの環境
IBM Quantum PlatformまたはIBM Cloudのいずれかを通じて IBM Quantum ハードウェアにアクセスする。IBM Quantum Platform は無料アクセス版のオープンプランとプレミアムプランが存在する。オープンプランでも一ヶ月あたり最大10分のリソースが利用可能。プレミアムプランではサブスク形式らしい。今回はオープンプランの方法を紹介する。
IBM CloudはLite(無料)とStandard(従量課金制)がある。ライトプランでは量子シミュレータで量子回路のデバッグなどの勉強ができる。Standardは使った分だけ料金が請求される。
IBM Quantumのアカウント作成とトークン発行
ここからログイン。LinkedInなどSSOが使える。
アカウントページでトークンを発行する。
Notebookにおいて以下のように認証を行う。
from qiskit_ibm_runtime import QiskitRuntimeService
# IBM Quantum アカウントの保存とデフォルト設定
QiskitRuntimeService.save_account(channel="ibm_quantum", token="<MY_IBM_QUANTUM_TOKEN>", set_as_default=True)
# 保存した設定を読み出す
service = QiskitRuntimeService()
最近身近なところで漏洩を見かけたので念の為注意書きしておくが、このトークンは他者に知られてはいけないので、GitHubなどにアップロードしたりしてはならない。もしGitHubなどに上げたい場合、環境変数を読み込むようにするか、あるいは別ファイルにトークンを書き出してそれをPython側から読み出すようにしてやり、そのトークンファイルは.gitignoreに追加してやる必要がある。
サンプルコードを実行
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
# 空のcircuitを作成
example_circuit = QuantumCircuit(2)
example_circuit.measure_all()
backend = service.least_busy(operational=True, simulator=False)
sampler = Sampler(backend)
job = sampler.run([example_circuit])
print(f"job id: {job.job_id()}")
result = job.result()
print(result)
ジョブIDが保存されてからジョブが実行されるまで結構かかる。気長に待つ。
……
気長にYoutubeでも見ていたが一向にジョブが流れない。IBM Quantum Platform からジョブの待ち時間が見れる。
はい。3時間待ちですね。
翌日、仕事から帰宅したら計算が終了したので見てみる。
PrimitiveResult([PubResult(data=DataBin(meas=BitArray(<shape=(), num_shots=4096, num_bits=2>)), metadata={'circuit_metadata': {}})], metadata={'version': 2})
うーん? 実際にジョブの様子をまず知るべきだ。
ジョブの状態をPythonから見る
import datetime
from qiskit_ibm_runtime import QiskitRuntimeService
three_months_ago = datetime.datetime.now() - datetime.timedelta(days=90)
service = QiskitRuntimeService()
jobs_in_last_three_months = service.jobs(created_after=three_months_ago) # 過去三ヶ月のジョブの情報を取得
jobs_in_last_three_months[:3] # 最初の3つを表示
[OUT]
[<RuntimeJob('csbk2htcfc40008ryf4g', 'sampler')>]
なるほど。
ジョブIDからジョブの結果を見る。
job_id = service.jobs(pending=False)[0].job_id()
print(job_id)
[Out]
csbk2htcfc40008ryf4g
retrieved_job = service.job(job_id)
retrieved_job.result()
[Out]
PrimitiveResult([PubResult(data=DataBin(meas=BitArray(<shape=(), num_shots=4096, num_bits=2>)), metadata={'circuit_metadata': {}})], metadata={'version': 2})
やっぱりこの結果が記念すべき最初の量子計算の結果のようだ。
QiskitのPrimitiveResultについて
PrimitiveResultオブジェクトは量子回路の実行結果を含んでいる。
PubResultは結果のリストとなっており、今回は1つだけ含まれている。
DataBin: データをバイナリ形式で格納するオブジェクト
BitArray: 測定結果のビット列を格納したもの
<shape=(), num_shots=4096, num_bits=2>
は データが1次元配列であり、4,096回試行されたもので、測定結果が2ビット(11や01など)であることを意味しているようだ。
今のところこれ以上のデータはわからない。
が、とりあえず動いた。次回はベル状態の生成を行う。