Skip to main content
IBM Quantum Platform

빠른 시작

이 가이드에서는 해당 qiskit-paulice 패키지의 최소 실행 가능한 예제를 보여줍니다. 우리는 클리포드 회로 실행 중 오류를 탐지하기 위해 시공간 파울리 검증을 사용한 다음, 오류가 탐지되지 않은 샘플만을 사후 선별합니다. 정확도 향상을 수치화한, 보다 상세한 종단간 워크플로를 확인하려면 심층 튜토리얼을 참조하십시오.

워크플로우 단계

  1. 입력 데이터를 준비합니다: 클리포드 페이로드 회로, 체크 연산을 수행할 대상/보조 큐비트, 그리고 잡음 모델.
  2. 적절한 시공간 파울리 검사 조건을 찾아 회로에 추가하십시오.
  3. 체크된 회로의 신호를 측정해 보십시오.
  4. 오류가 감지되지 않은 샘플만 선별하여 게시하십시오.

1. 입력 데이터 준비하기

add_pauli_checks 최소 하나의 단말 측정이 포함된 클리포드 회로, 검증을 구현하는 데 사용될 대상 큐비트, 그리고 후보 검증에 대한 점수를 매기는 데 사용되는 노이즈 모델을 입력으로 받습니다. ibm_boston여기서는 얕은 랜덤 클리포드 회로를 구축하고, 이를 물리적 큐비트로 구성된 1D 체인에 배치하며, 각 페이로드 큐비트를 인접한 보조 큐비트와 짝지은 뒤(따라서 검사 시 SWAP 게이트가 필요하지 않음), 백엔드 벤치마크 데이터를 바탕으로 대략적인 탈분극 잡음 모델을 도출합니다.

import numpy as np
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_paulice.layout import get_check_qubits
from qiskit_paulice.noise_models import NoiseModel

# Backend and a 1D chain of physical qubits to run on
backend = QiskitRuntimeService().backend("ibm_boston")
layout = [68, 69, 78, 89, 90, 91, 98, 111, 112, 113, 119, 133]

# A shallow brickwork random Clifford payload circuit
rng = np.random.default_rng(1764)
circuit = QuantumCircuit(len(layout))
circuit.h(range(circuit.num_qubits))
for d in range(4):
    for i in range(d % 2, circuit.num_qubits - 1, 2):
        circuit.cz(i, i + 1)
    for q in range(circuit.num_qubits):
        if rng.integers(0, 2):
            circuit.sx(q)
        if rng.integers(0, 2):
            circuit.s(q)
circuit.measure_all()

# Pair each payload qubit with a neighboring ancilla to host a check (no SWAPs needed)
target_qubits, ancilla_qubits = get_check_qubits(backend.coupling_map, layout)

# A rough depolarizing noise model from backend benchmark data, used to score checks
noise_model = NoiseModel.from_backend(
    backend, layout, uniform_gate_noise=True
)

circuit.draw("mpl", fold=-1)

Output:

Output of the previous code cell

2. 시공간 파울리 검사 조건 찾기 및 추가하기

add_pauli_checks 각 대상 큐비트에 대해 효과적이고 경량인 검사 방법을 찾아 회로에 추가한 뒤, 일련의 CheckedCircuit 인스턴스 시퀀스를 반환합니다. 이 CheckedCircuit 사례들에는 대상 큐비트당 1회 검사까지, 0 검사 횟수가 점차 증가하는 경우가 포함되어 있습니다. 각 검사는 회로 깊이가 약간 증가하는 대가로 오류 탐지 능력을 향상시킵니다. 이 예제에서는 모든 대상 큐비트에 대한 검사가 포함된 회로를 사용할 것입니다.

from qiskit_paulice import add_pauli_checks

# The circuit has virtual qubits, so we specify our target qubits with virtual indices
target_qubits_v = [layout.index(q) for q in target_qubits]

# Add spacetime Pauli checks
checked_circuit = add_pauli_checks(circuit, target_qubits_v, noise_model)[-1]
checked_circuit.circuit.draw("mpl", fold=-1, scale=0.4, idle_wires=False)

Output:

Output of the previous code cell

3. 점검한 회로의 신호를 샘플링한다

ibm_boston샘플링을 수행하기 전에, 검증된 회로를 물리적 큐비트(initial_layout = layout + ancilla_qubits)로 변환하고 의 기본 기저 게이트 집합으로 변환합니다. 잡음이 있는 QPU를 모방하기 위해, 체크를 선택하는 데 noise_model 사용된 오류율과 일치하는 잡음이 있는 Aer 안정화 백엔드를 사용하여 샘플링합니다.

from qiskit import transpile
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel as AerNoiseModel
from qiskit_aer.noise import ReadoutError, depolarizing_error

# Transpile once: lay the checked circuit out on our qubits and into the native basis
isa_circuit = transpile(
    checked_circuit.circuit,
    backend,
    initial_layout=layout + ancilla_qubits,
    optimization_level=0,
)

# Build an Aer noise model matching the depolarizing model used to pick checks
aer_noise = AerNoiseModel()
aer_noise.add_all_qubit_quantum_error(
    depolarizing_error(noise_model.gate_noise, 2), ["cz"]
)
p = noise_model.readout_noise
aer_noise.add_all_qubit_readout_error(ReadoutError([[1 - p, p], [p, 1 - p]]))
simulator = AerSimulator(method="stabilizer", noise_model=aer_noise)

counts = (
    simulator.run(isa_circuit, shots=1000, seed_simulator=1764)
    .result()
    .get_counts()
)
print(f"sampled {sum(counts.values())} shots")

Output:

sampled 1000 shots

4. 오류가 감지되지 않은 사후 선별 샘플

get_postselection_method 각 샷을 해당 신드롬 벡터에 매핑하며, 신드롬 값이 모두 0인 샷, 즉 오류 검출에서 오류가 발견되지 않은 샷만 유지합니다. 표시된 샷을 제외하면, 남아 있는 분포에서 감지된 오류가 제거되어 샘플링 빈도는 낮아지지만 정확도는 향상됩니다. 정량적인 충실도 비교에 대해서는 튜토리얼 을 참고하세요.

# Keep only the shots in which no check reported an error
ps_fn = checked_circuit.get_postselection_method()
counts_postselected = {
    bs: n for bs, n in counts.items() if not ps_fn(bs).any()
}

kept, total = sum(counts_postselected.values()), sum(counts.values())
print(f"kept {kept} of {total} shots ({kept / total:.0%})")

Output:

kept 927 of 1000 shots (93%)
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.