今回は単一振幅といって特定のビット配列の振幅を求めます。振幅の絶対値の二乗はそのビット列の出現確率と対応しています。すべての状態ベクトルの振幅を同時に表現するのは150量子ビットではすでに無理なので、単一振幅を求めます。
参考:
Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
SPDX-License-Identifier: BSD-3-Clause
ツールを読み込み適当な回路を作ります。
import cirq
from cirq.testing import random_circuit
import cupy as cp
import numpy as np
import time
from cuquantum import contract, CircuitToEinsum
num_qubits = 150
n_moments = 6
op_density = 0.9
gate_domain = {cirq.H: 1,
cirq.S: 1,
cirq.T: 1,
cirq.CNOT: 2,
cirq.CZ: 2}
circuit = random_circuit(num_qubits, n_moments, op_density=op_density, gate_domain=gate_domain, random_state=6)
#print(circuit)
そして実行です。今回は特に考えず全部0のビット配列の振幅を求めます。
l = [0 for _ in range(num_qubits)]
bitstring = ''.join(map(str, l))
print(bitstring)
start1 = time.time()
myconverter = CircuitToEinsum(circuit, dtype='complex128', backend=cp)
expression, operands = myconverter.amplitude(bitstring)
print("preprocess:", time.time() - start1)
start2 = time.time()
amplitude = contract(expression, *operands)
print("process:", time.time() - start2)
print(amplitude)
print(np.abs(amplitude)**2)
早速実行結果です。今回はNVIDIAのGPUのA100でメモリサイズ80Gのマシンを使いました。
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
preprocess: 0.03520393371582031
process: 8.503039121627808
(-3.215549355384471e-13-1.3319241534803108e-13j)
1.2113779607537728e-25
前処理は0.03秒。実際の150量子ビットの処理は8.5秒で終わりました。簡単な回路でしたのですぐに終わりました。以上です。