ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

การทดลองระดับ Utility-Scale ครั้งที่ 1

หมายเหตุ

Tamiya Onodera (5 กรกฎาคม 2024)

ดาวน์โหลด pdf ของเลคเชอร์ต้นฉบับ โปรดทราบว่าโค้ดบางส่วนอาจล้าสมัย เนื่องจากเป็นภาพนิ่ง

เวลา QPU โดยประมาณสำหรับการทดลองนี้คือ 45 วินาที

1. บทนำสู่ utility paper​

ในบทเรียนนี้ เราจะรัน Circuit ระดับ utility-scale ที่ปรากฏในสิ่งที่เราเรียกกันอย่างไม่เป็นทางการว่า "utility paper" ซึ่งตีพิมพ์ใน Nature เล่มที่ 618 วันที่ 15 มิถุนายน 2023 บทความนี้กล่าวถึงวิวัฒนาการตามเวลาของแบบจำลอง Ising แบบสองมิติในสนามขวาง โดยเฉพาะอย่างยิ่งพวกเขาพิจารณา dynamics ตามเวลาของ Hamiltonian

H=HZZ+HX=−J∑(i,j)ZiZj+h∑iXiH = H_{ZZ} + H_X = - J \sum_{(i,j)} Z_i Z_j + h \sum_{i} X_i

โดยที่ J>0J > 0 คือการคัปปลิ้งของสปินที่อยู่ติดกันที่ i<ji < j และ hh คือสนามขวางแบบ global พวกเขาจำลอง spin dynamics จากสถานะเริ่มต้นโดยใช้ first-order Trotter decomposition ของ time-evolution operator

exp⁡(−iHZZδt)=∏(i,j)exp⁡(iJδtZiZj)=∏(i,j)RZiZj(−2Jδt)exp⁡(−iHXδt)=∏iexp⁡(−ihδtXi)=∏iRXi(2hδt)\begin{aligned} \exp(-i H_{ZZ} \delta t) &= \prod_{(i,j)} \exp (i J \delta t Z_i Z_j) = \prod_{(i,j)} \mathrm{R}_{Z_i Z_j} ( - 2 J \delta t) \\ \exp(-i H_X \delta t) &= \prod_{i} \exp (-i h \delta t X_i ) = \prod_{i} \mathrm{R}_{X_i} ( 2 h \delta t) \end{aligned}

โดยที่เวลาวิวัฒนาการ TT ถูกแบ่งเป็น T/δtT / \delta t Trotter steps และ RZiZj(θJ)\mathrm{R}_{Z_i Z_j}(\theta_J) และ RXi(θh)\mathrm{R}_{X_i}(\theta_h) คือ ZZZZ และ XX rotation Gate ตามลำดับ

พวกเขารันการทดลองบน IBM Quantum® Eagle processor ซึ่งเป็นอุปกรณ์ 127 Qubit ที่มีการเชื่อมต่อแบบ heavy-hex โดยใช้ XX interactions กับ Qubit ทั้งหมด และ ZZZZ interactions สำหรับทุกขอบของ coupling map โปรดทราบว่า ZZZZ interactions ทั้งหมดไม่สามารถใช้พร้อมกันได้เนื่องจาก "data dependance" ดังนั้นพวกเขาจึงจัดสีให้ coupling map เพื่อจัดกลุ่มเป็น layer ต่าง ๆ โดย layer เดียวกันจะได้รับสีเดียวกันและสามารถรันพร้อมกันได้

นอกจากนี้ เพื่อความง่ายในการทดลอง พวกเขาเน้นที่กรณี θJ=−π/2\theta_J=-\pi /2

ผลงานสำคัญของบทความนี้คือพวกเขาสร้าง quantum circuit ในขนาดที่เกินความสามารถของ statevector simulation รันบนคอมพิวเตอร์ควอนตัมที่มีนอยส์ และประสบความสำเร็จในการดึงผลลัพธ์ที่เชื่อถือได้ นั่นคือพวกเขาแสดงให้เห็นถึงประโยชน์ของคอมพิวเตอร์ควอนตัมที่มีนอยส์ ในการทำเช่นนี้ พวกเขาใช้ zero-noise extrapolation (ZNE) ร่วมกับ probabilistic error amplification (PEA) เพื่อลดความผิดพลาดจากอุปกรณ์ที่มีนอยส์

ตั้งแต่นั้นมา เราเรียกการทดลองและ Circuit ลักษณะนี้ว่า "utility-scale"

1.1 เป้าหมายของคุณ​

เป้าหมายในบทเรียนนี้คือการสร้าง Circuit ระดับ utility-scale และรันบน Eagle processor การดึงผลลัพธ์ที่เชื่อถือได้นั้นอยู่นอกขอบเขตของ notebook นี้ ส่วนหนึ่งเพราะ PEA เป็นฟีเจอร์ทดลองใน Qiskit ณ ขณะที่เขียน และส่วนหนึ่งเพราะการใช้ ZNE กับ PEA จะใช้เวลามาก

โดยเฉพาะ คุณจะถูกขอให้สร้างและรันวงจรที่สอดคล้องกับรูปที่ 4b ของบทความ และพล็อตจุด "unmitigated" ของคุณเอง ดังที่คุณเห็น มันเป็นวงจร 127 คิวบิต ×\times 60 เลเยอร์ (20 ขั้นตอน Trotter) โดยมี ⟨Z62⟩\langle Z_{62} \rangle เป็น observable image.png ฟังดูเป็นเรื่องใหญ่ใช่ไหม?   ไม่ต้องกังวล บทเรียนสามบทสุดท้ายของหลักสูตรนี้จะเป็นบันไดขั้นแรก เริ่มต้น เราจะสาธิตการทดลองขนาดเล็กกว่าซึ่งเป็นการสร้างและรันบนอุปกรณ์จำลอง วงจร 27 คิวบิต ×\times 6 เลเยอร์ (2 ขั้นตอน Trotter) โดยมี ⟨Z13⟩\langle Z_{13} \rangle เป็น observable

เพียงเท่านี้สำหรับบทนำ ขอให้สนุกกับการผจญภัยระดับ utility-scale!

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "qiskit": "qiskit", "qiskit_aer": "qiskit-aer", "qiskit_ibm_runtime": "qiskit-ibm-runtime", "rustworkx": "rustworkx"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import qiskit

qiskit.__version__
'2.0.2'
#!pip install qiskit_ibm_runtime
#!pip install qiskit_aer
import matplotlib.pyplot as plt
import numpy as np
import rustworkx as rx

from qiskit import QuantumCircuit, transpile
from qiskit.circuit import Parameter
from qiskit.circuit.library import YGate
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import (
QiskitRuntimeService,
fake_provider,
EstimatorV2 as Estimator,
)
from qiskit_aer import AerSimulator
service = QiskitRuntimeService()

2. การเตรียมการ​

2.1 สร้าง RZZ(-π\pi / 2)​

ก่อนอื่น สังเกตว่า RZZ gate โดยทั่วไปต้องใช้ CXCX gate สองตัว

from qiskit.circuit.library import RZZGate

θ_h = Parameter("$\\theta_h$")
qc1 = QuantumCircuit(2)
qc1.append(RZZGate(θ_h), [0, 1])
qc1.decompose(reps=1).draw("mpl")

Output of the previous code cell

ดังที่กล่าวไว้ข้างต้น เราเน้นที่ RZZ gate ที่มีมุมเฉพาะ -π\pi / 2 สำหรับการทดลองนี้ ดังที่แสดงในบทความ สามารถสร้างได้ด้วย CXCX gate เพียงตัวเดียว

qc2 = QuantumCircuit(2)

qc2.sdg([0, 1])
qc2.append(YGate().power(1 / 2), [1])
qc2.cx(0, 1)
qc2.append(YGate().power(1 / 2).adjoint(), [1])

qc2.draw("mpl")

Output of the previous code cell

เราสร้าง Gate จาก Circuit นี้สำหรับการอ้างอิงในอนาคต

rzz = qc2.to_gate(label="RZZ")

ลองใช้ rzz ที่สร้างขึ้นใหม่แบบสุ่ม

qc3 = QuantumCircuit(3)
qc3.append(rzz, [0, 1])
qc3.append(rzz, [0, 2])
display(qc3.draw("mpl"))
# display(qc.decompose(reps=1).draw("mpl"))

Output of the previous code cell

ก่อนนำไปใช้ต่อ ลองตรวจสอบความเท่าเทียมเชิงตรรกะของ qc1 (RZZ gate) สำหรับ -pi/2 กับ rzz หรือ qc2 gate ที่สร้างขึ้น:

from qiskit.quantum_info import Operator

op1 = Operator(qc1.assign_parameters([-np.pi / 2]))
op2 = Operator(qc2)

op1.equiv(op2)
True

2.2 การจัดสีให้ coupling map​

ลองศึกษาวิธีจัดสีให้ coupling map ของ Backend ซึ่งจำเป็นสำหรับการจัดกลุ่ม ZZZZ interactions เป็น layer

เริ่มต้น ลองแสดงภาพ coupling map ของ Backend โปรดทราบว่า coupling map ของอุปกรณ์ IBM Quantum ปัจจุบันทุกตัวเป็นแบบ heavy-hexagonal

backend = service.least_busy(operational=True, simulator=False)

backend.coupling_map.draw()

Output of the previous code cell

สำหรับการจัดสี coupling map เราใช้ rustworkx ซึ่งเป็น Python package สำหรับทำงานกับกราฟและ complex networks โดยมีอัลกอริทึมการจัดสีหลายแบบ ซึ่งล้วนเป็น heuristic และจึงไม่รับประกันว่าจะหาการจัดสีที่น้อยที่สุด

อย่างไรก็ตาม เนื่องจาก heavy-hex graph เป็น bipartite เราจึงเลือกใช้ graph_bipartite_edge_color ซึ่งควรหาการจัดสีที่น้อยที่สุดสำหรับกราฟเหล่านี้

def color_coupling_map(backend):
graph = backend.coupling_map.graph
undirected_graph = graph.to_undirected(multigraph=False)
edge_color_map = rx.graph_bipartite_edge_color(undirected_graph)
if edge_color_map is None:
edge_color_map = rx.graph_greedy_edge_color(undirected_graph)
# build a map from color to a list of edges
edge_index_map = undirected_graph.edge_index_map()
color_edges_map = {color: [] for color in edge_color_map.values()}
for edge_index, color in edge_color_map.items():
color_edges_map[color].append(
(edge_index_map[edge_index][0], edge_index_map[edge_index][1])
)
return edge_color_map, color_edges_map

Heavy-hexagonal graph ควรถูกทาสีสามสี ลองตรวจสอบสิ่งนี้กับ coupling map ข้างต้น

edge_color_map, color_edges_map = color_coupling_map(backend)
print(
f"{backend.name}, {backend.num_qubits}-qubit device, {len(color_edges_map.keys())} colors assigned."
)
ibm_strasbourg, 127-qubit device, 3 colors assigned.

ใช่แล้ว!

เพื่อความสนุก ลองทาสี coupling map ตามการจัดสีที่ได้ โดยใช้ฟีเจอร์ visualization ของ rustworkx

color_str_map = {0: "green", 1: "red", 2: "blue"}

undirected_graph = backend.coupling_map.graph.to_undirected(multigraph=False)
for i in undirected_graph.edge_indices():
undirected_graph.get_edge_data_by_index(i)["color"] = color_str_map[
edge_color_map[i]
]

rx.visualization.graphviz_draw(
undirected_graph, method="neato", edge_attr_fn=lambda edge: {"color": edge["color"]}
)

Output of the previous code cell

3. แก้ปัญหาวิวัฒนาการตามเวลาแบบ Trotterized ของแบบจำลอง Ising แบบ 2D​

ลองสร้าง routine เพื่อสร้าง Circuit ของ utility paper สำหรับวิวัฒนาการตามเวลาของแบบจำลอง Ising แบบ 2D โดย routine รับสามพารามิเตอร์ ได้แก่ Backend จำนวนเต็มที่บอกจำนวน Trotter steps และค่า Boolean ที่ควบคุมการแทรก barrier

def get_utility_circuit(backend, num_steps: int, barrier: bool = False):
num_qubits = backend.num_qubits
_, color_edges_map = color_coupling_map(backend)
θ_h = Parameter("$\\theta_h$")
qc = QuantumCircuit(num_qubits)

for i in range(num_steps):
qc.rx(θ_h, range(num_qubits))

for _, edge_list in color_edges_map.items():
for edge in edge_list:
qc.append(rzz, edge)

if barrier:
qc.barrier()
return qc

โปรดทราบว่าเราได้ทำ qubit mapping และ routing ของ Circuit ที่สร้างขึ้นเองแล้ว ดังนั้นเมื่อเรา transpile Circuit ในภายหลัง เราจะไม่ (และ__ไม่ควร__) ขอให้ Transpiler ทำ qubit mapping และ routing ดังที่คุณจะเห็นในอีกสักครู่ เราเรียกใช้ด้วย optimization level 1 และ layout method เป็น "trivial"

ถัดไป เราสร้าง routine ง่าย ๆ เพื่อรับข้อมูลเกี่ยวกับ Circuit ที่สร้างขึ้นเพื่อตรวจสอบเบื้องต้น

def get_circuit_info(qc: QuantumCircuit, reps: int = 0):
qc0 = qc.decompose(reps=reps)
return (
f"{qc0.num_qubits} qubits × {qc0.depth(lambda x: x.operation.num_qubits == 2)} layers ({qc0.depth()}-depth)"
+ ", "
+ f"""Gate breakdown: {", ".join([f"{k.upper()} {v}" for k, v in qc0.count_ops().items()])}"""
)

ลองเรียกใช้ routine เหล่านี้กัน คุณควรเห็นวงจร 27 คิวบิต ×\times 15 เลเยอร์ (5 ขั้นตอน Trotter) เนื่องจากอุปกรณ์จำลองมี 28 edges ควรมีเกตพัวพัน 28*5 ตัว

backend = fake_provider.FakeTorontoV2()
num_steps = 5
qc = get_utility_circuit(backend, num_steps, True)

display(qc.draw(output="mpl", fold=-1))
print(get_circuit_info(qc, reps=0))
print(get_circuit_info(qc, reps=1))

Output of the previous code cell

27 qubits × 15 layers (20-depth), Gate breakdown: CIRCUIT-165 140, RX 135, BARRIER 5
27 qubits × 15 layers (60-depth), Gate breakdown: SDG 280, UNITARY 280, CX 140, R 135, BARRIER 5

4. แก้ปัญหาเวอร์ชัน 27 Qubit​

เราจะสาธิตการทดลองขนาดเล็กกว่าของ utility experiment เราสร้างวงจรขนาด 27 คิวบิต ×\times 6 เลเยอร์ (2 ขั้นตอน Trotter) โดยมี ⟨Z13⟩\langle Z_{13} \rangle เป็น observable และรันทั้งบน AerSimulator และอุปกรณ์จำลอง

แน่นอน เราทำตาม workflow สี่ขั้นตอน "Qiskit pattern" ซึ่งประกอบด้วย Map, Optimize, Execute และ Post-Process โดยเฉพาะ:

  • แมป input แบบคลาสสิกไปยังการคำนวณเชิงควอนตัม
  • ปรับปรุง Circuit สำหรับการคำนวณเชิงควอนตัม
  • รัน Circuit โดยใช้ primitive
  • ประมวลผลและส่งคืนผลลัพธ์ในรูปแบบคลาสสิก

ด้านล่าง เรามีขั้นตอน Map สำหรับสร้าง Circuit ของการทดลองขนาดเล็ก จากนั้นมีชุด Optimize และ Execute ชุดหนึ่งสำหรับ AerSimulator และอีกชุดสำหรับอุปกรณ์จำลอง สุดท้ายมีขั้นตอน Post-Process เพื่อพล็อตผลลัพธ์

4.1 ขั้นตอนที่ 1: Map​

backend = fake_provider.FakeTorontoV2() # a 27 qubit fake device.
num_steps = 2
qc = get_utility_circuit(backend, num_steps)
obs = SparsePauliOp.from_sparse_list(
[("Z", [13], 1)], num_qubits=backend.num_qubits
) # Falcon
angles = [
0,
0.1,
0.2,
0.3,
0.4,
0.5,
0.6,
0.7,
0.8,
1.0,
np.pi / 2,
] # We try 11 angles for theta_h.

4.2 ขั้นตอนที่ 2 และ 3: Optimize และ Execute (Simulator)​

backend_sim = AerSimulator()
transpiled_qc_sim = transpile(
qc, backend_sim, optimization_level=1, layout_method="trivial"
)
transpiled_obs_sim = obs.apply_layout(layout=transpiled_qc_sim.layout)

print(get_circuit_info(qc, reps=1))
print(get_circuit_info(transpiled_qc_sim, reps=1))
27 qubits × 6 layers (23-depth), Gate breakdown: SDG 112, UNITARY 112, CX 56, R 54
27 qubits × 6 layers (16-depth), Gate breakdown: U3 80, CX 56, R 54, U1 32, U 28

ผู้ใช้รายหนึ่งรัน cell ถัดไปบน MacBook Pro พร้อม Intel Core i7 Processor 2.3 GHz quad-core พร้อม RAM 32GB 3LPDDR4X ที่รัน macOS 14.5 ใช้เวลา wall time 161ms แต่ละเครื่องจะแตกต่างกันเล็กน้อย

%%time
params = [[p] for p in angles]
estimator = Estimator(mode=backend_sim)
pub = (transpiled_qc_sim, transpiled_obs_sim, params)
result_sim = estimator.run([pub]).result()
CPU times: user 231 ms, sys: 186 ms, total: 417 ms
Wall time: 111 ms

4.3 ขั้นตอนที่ 2 และ 3: Optimize และ Execute (fake device)​

backend_fake = fake_provider.FakeTorontoV2()
transpiled_qc_fake = transpile(
qc, backend_fake, optimization_level=1, layout_method="trivial"
)
transpiled_obs_fake = obs.apply_layout(layout=transpiled_qc_fake.layout)

print(get_circuit_info(qc, reps=1))
print(get_circuit_info(transpiled_qc_fake, reps=1))
27 qubits × 6 layers (23-depth), Gate breakdown: SDG 112, UNITARY 112, CX 56, R 54
27 qubits × 6 layers (49-depth), Gate breakdown: SDG 324, U1 274, H 162, CX 56, U3 14

เมื่อผู้ใช้คนเดียวกันรันเซลล์ถัดไปด้วยสภาพแวดล้อมเดียวกันกับข้างต้น ใช้เวลา 2 นาที 19 วินาที ตามเวลาจริง (Wall Time) การรันวงจรบนอุปกรณ์จำลองจะเรียกใช้การจำลองที่มีนอยส์ซึ่งใช้เวลานานกว่าการจำลองแบบ exact มาก เราแนะนำว่าอย่ารันวงจรที่ใหญ่กว่านี้ (เช่น 27 คิวบิต ×\times 9 เลเยอร์ ด้วย 3 ขั้นตอน Trotter) บนอุปกรณ์จำลอง

%%time
params = [[p] for p in angles]
estimator = Estimator(mode=backend_fake)
pub = (transpiled_qc_fake, transpiled_obs_fake, params)
result_fake = estimator.run([pub]).result()
CPU times: user 4min 42s, sys: 9.35 s, total: 4min 51s
Wall time: 38.3 s

4.4 ขั้นตอนที่ 4: Post-process​

เราพล็อตผลลัพธ์จากการจำลองแบบ exact และมีนอยส์ คุณจะเห็นผลกระทบจากนอยส์ที่รุนแรงบน FakeToronto

plt.plot(angles, result_fake[0].data.evs, "o", label="Fake Device")
plt.plot(angles, result_sim[0].data.evs, "o", label="AerSimulator")
plt.xlabel("$\\mathrm{R_x}$ angle $\\theta_h$")
plt.title("$\\langle Z_{13} \\rangle$")
plt.legend()
plt.show()

Output of the previous code cell

5. แก้ปัญหาเวอร์ชัน 127 Qubit​

เป้าหมายของคุณคือการรัน utility-scale experiment ตามที่กล่าวไว้ในตอนต้น คุณจะสร้างและรันวงจรขนาด 127 คิวบิต และ 60 เลเยอร์ (20 ขั้นตอน Trotter) โดยมี ⟨Z62⟩\langle Z_{62} \rangle เป็น observable เราแนะนำให้ลองทำเองโดยใช้โค้ดเวอร์ชัน 27 คิวบิต เมื่อเหมาะสม แต่มีเฉลยให้ที่นี่

เฉลย:

5.1 ขั้นตอนที่ 1: Map​

# backend_map = service.backend("ibm_brisbane")
backend_map = service.least_busy(operational=True, simulator=False)

num_steps = 20
qc = get_utility_circuit(backend_map, num_steps)
obs = SparsePauliOp.from_sparse_list(
[("Z", [62], 1)], num_qubits=backend_map.num_qubits
) # Eagle
angles = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0, np.pi / 2]

5.2 ขั้นตอนที่ 2 และ 3: Optimize และ Execute​

โปรดทราบว่า coupling map ของ Eagle processor มี 144 ขอบ

# backend = service.backend("ibm_brisbane")
backend = backend_map

transpiled_qc = transpile(qc, backend, optimization_level=1, layout_method="trivial")
transpiled_obs = obs.apply_layout(layout=transpiled_qc.layout)

print(get_circuit_info(qc, reps=1))
print(get_circuit_info(transpiled_qc))
156 qubits × 60 layers (221-depth), Gate breakdown: SDG 7040, UNITARY 7040, CX 3520, R 3120
156 qubits × 60 layers (201-depth), Gate breakdown: RZ 11933, SX 6240, CZ 3520
params = [[p] for p in angles]
estimator = Estimator(mode=backend)
pub = (transpiled_qc, transpiled_obs, params)
job = estimator.run([pub])

job_id = job.job_id()
print(f"job id={job_id}")
job id=d1479n6qf56g0081sxa0

5.3 การประมวลผลภายหลัง​

เราให้ค่าสำหรับจุด "mitigated" ใน Figure 4b ของ utility paper พล็อตค่าเหล่านี้ร่วมกับผลลัพธ์ของคุณ

result_paper = [
1.0171,
1.0044,
0.9563,
0.9602,
0.8394,
0.8120,
0.5466,
0.4556,
0.1953,
0.0141,
0.0117,
]

# REPLACE WITH YOUR OWN JOB ID
job = service.job(job_id)

plt.plot(angles, job.result()[0].data.evs, "o", label=f"{job.backend().name}")
plt.plot(angles, result_paper, "o", label="Utility Paper")
plt.xlabel("$\\mathrm{R_x}$ angle $\\theta_h$")
plt.title("$\\langle Z_{62} \\rangle$")
plt.legend()
plt.show()

Output of the previous code cell

ผลลัพธ์ของคุณคล้ายกับ "unmitigated" ใน Figure 4b ไหม?   อาจแตกต่างกันมาก ขึ้นอยู่กับอุปกรณ์และสภาพของมันในขณะทดลอง ไม่ต้องกังวลกับผลลัพธ์ สิ่งที่เราจะตรวจสอบคือว่าคุณทำโค้ดได้ถูกต้องหรือไม่ ถ้าทำได้ ขอแสดงความยินดี คุณได้ก้าวถึงจุดเริ่มต้นของยุค utility แล้ว

เช่นเดียวกับใน Utility paper นักวิทยาศาสตร์ทั่วโลกได้ทุ่มเทความคิดสร้างสรรค์อย่างมากในการดึงผลลัพธ์ที่มีความหมายแม้จะมีนอยส์ เป้าหมายสูงสุดของความพยายามร่วมกันนี้คือ quantum advantage: สถานะที่คอมพิวเตอร์ควอนตัมสามารถแก้ปัญหาบางอย่างที่มีประโยชน์ในอุตสาหกรรมได้เร็วกว่า มีความเที่ยงตรง (fidelity) สูงกว่า หรือถูกกว่าคอมพิวเตอร์คลาสสิก สิ่งนี้ไม่น่าจะเป็นเหตุการณ์เดียว แต่เป็นยุคสมัยที่การจำลองผลลัพธ์ควอนตัมแบบคลาสสิกใช้เวลานานขึ้นเรื่อย ๆ จนกว่าจะถึงจุดที่ระยะเวลาที่ควอนตัมนำหน้าอยู่นั้นมีความสำคัญอย่างยิ่ง สิ่งหนึ่งที่ชัดเจนเกี่ยวกับ quantum advantage: เราจะไปถึงจุดนั้นได้ก็ต่อเมื่อผ่านการทดลองระดับ utility-scale เท่านั้น หากคอร์สนี้ทำให้คุณเข้าร่วมการแสวงหาที่เต็มไปด้วยความท้าทายและความสนุก เราจะยินดีมาก

อ้างอิง​