Skip to main content
IBM Quantum Platform

트랜스파일러

이 generate_boxing_pass_manager() 함수는 회로 명령어를 주석이 달린 상자로 묶을 수 있는 qiskit.transpiler.PassManager 를 만드는 데 유용하고 편리한 도구입니다. 이는 회로를 수동으로 그룹화하고 주석을 달아야 하는 번거로움을 덜어주는 간편한 대안이며, 워크플로우를 자동화하거나 다양한 회로 박스링 전략을 테스트하는 데 유용합니다.

이 안내서는 및 generate_boxing_pass_manager() 그 인수를 사용하는 방법을 설명합니다. 각 함수 인자의 효과를 명확히 설명하기 위해, 다음 섹션에서는 주로 아래의 회로를 참고할 것입니다.

from qiskit.circuit import Parameter, QuantumCircuit

circuit = QuantumCircuit(4, 7)
circuit.h(1)
circuit.h(2)
circuit.cz(1, 2)
circuit.h(1)
circuit.cx(1, 0)
circuit.cx(2, 3)
circuit.measure(range(1, 4), range(3))
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
for qubit in range(4):
    circuit.rz(Parameter(f"th_{qubit}"), qubit)
    circuit.rx(Parameter(f"phi_{qubit}"), qubit)
    circuit.rz(Parameter(f"lam_{qubit}"), qubit)
circuit.measure(range(4), range(3, 7))

circuit.draw("mpl", scale=0.8)
../_images/cf27e1ef03e51b2360c90165a4efeaa793da36083bb674774ca06c8181ef63dd.png

작업들을 상자로 묶기

이 인수는 True 또는 로 설정하여 2-큐비트 게이트를 상자로 묶을지 여부를 지정할 False 수 enable_gates 있습니다. 마찬가지로, 측정값을 그룹화할지 여부를 enable_measures 지정합니다. 다음 코드 조각은 게이트와 측정값이 모두 그룹화된 예시를 보여줍니다.

from samplomatic.transpiler import generate_boxing_pass_manager

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/b323dde8a5412e42359aef1831af92ed3702d2251547c663208dc084a2995276.png

그림에서 볼 수 있듯이, 패스 매니저는 두 가지 유형의 박스를 생성합니다. 하나는 2-큐비트 게이트로 구성된 단일 층을 포함하는 박스이고, 다른 하나는 측정으로 구성된 단일 층을 포함하는 박스입니다. 이러한 분리는 일반적으로 동질적인 연산 레이어를 대상으로 하는 노이즈 학습 및 완화 프로토콜의 표준 관행을 반영한 것입니다. 2-큐비트 게이트와 측정 연산은 이를 수용할 수 있는 가장 왼쪽 상자에 배치되며, 모든 1-큐비트 게이트는 그 앞에 오는 2-큐비트 게이트나 측정 연산과 같은 상자에 배치된다.

다음 코드는 enable_gates 가 로 설정된 예시를 보여줍니다 False. 보시다시피, 2큐비트 게이트는 상자로 묶여 있지 않으며, 그 앞에 오는 단일 큐비트 게이트도 마찬가지입니다.

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=False,
    enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/3fc8e660b0c7eff1f5aa2e571d064f91b3eb2738c5990727e026a8ffe1101a1c.png

상자에 주석을 달 방법을 선택하세요

반환된 회로에 포함된 모든 2-큐비트 게이트와 측정 박스에는 왼쪽 방향 주석이 지정되어 있습니다. 특히, 2-큐비트 게이트가 포함된 모든 상자에는 기호가 표시되어 있습니다 Twirl. 측정 상자의 경우, 사용자는 Twirl, BasisTranform (이 로 mode 설정된 경우 "measure") 또는 둘 다 중에서 선택할 수 있습니다. 다음 코드는 모든 상자가 회전된 회로를 생성하며, 측정 상자에는 추가로 표시가 붙습니다 BasisTranform.

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=True,
    measure_annotations="all",
)
transpiled_circuit = boxing_pass_manager.run(circuit)

노이즈 주입을 위해 회로를 준비하십시오

이 기능을 사용하면 inject_noise_targets 어떤 상자에 주석을 InjectNoise 달지 지정할 수 있습니다. 예를 들어, 다음 코드는 두 큐비트 게이트 상자에는 InjectNoise 주석이 있지만 측정 상자에는 주석이 없는 회로를 생성합니다.

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=True,
    inject_noise_targets="gates",
)
transpiled_circuit = boxing_pass_manager.run(circuit)

회로에 단일 큐비트 게이트 수준에서 동등한 두 개 이상의 박스가 포함되어 있다면, 이들 모두에는 동일한 InjectNoise 주석이 달립니다 ref. 따라서, 반환된 회로에서 고유한 ref‘s’의 개수는 고유한 상자의 개수와 같다.

의 값은 InjectNoise 주석에 영향을 inject_noise_strategy 미칩니다. 가능한 값은 다음과 같습니다.

  • modifier_ref='': 노이즈 맵에서 샘플링을 수행하기 전에 맵을 수정할 필요가 없는 경우에 권장됩니다.
  • modifier_ref=ref: 모든 노이즈 맵을 동일한 배율로 균일하게 확대·축소해야 할 때 권장됩니다.
  • :의 고유한 값 modifier_ref: 모든 노이즈 맵을 서로 다른 배율로 조정해야 할 때 권장됩니다.

다음 코드는 두 큐비트 게이트 상자에 고유한 값을 modifier_ref 가진 주석이 InjectNoise 부여된 회로를 생성합니다.

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=True,
    inject_noise_targets="gates",
    inject_noise_strategy="individual_modification",
)
transpiled_circuit = boxing_pass_manager.run(circuit)

회전 전략 선택하기

복싱 패스 관리자는 먼저 어떤 얽힘 게이트와 측정 지침이 동일한 상자에 표시되어야 하는지 선택하는 것으로 시작합니다. 이 작업이 완료되면, 박스는 일반적으로 전체 너비를 차지하지 않게 되며, 회로에서 활성 상태이거나 백엔드 대상에 존재하는 큐비트 중 일부만 포함하게 될 것입니다. 복싱 패스 매니저의 일반적인 구성에서, 박스 명령어가 작용하는 모든 큐비트는 트위링 처리되므로(박스 내부의 명령어가 작용하지 않는 큐비트조차도 포함), 부분 폭 박스를 사용하면 트위링의 노이즈 조정 효과에 영향을 미칩니다. 유휴 상태의 큐비트는 회전하지 않으며, 예를 들어 박스 효과가 적용되는 동안 코히어런트 오류가 누적될 수 있다. 이 기능은 각 상자가 보유한 큐비트를 확장할 수 있는 옵션을 제공하여 twirling_strategy , 유휴 큐비트의 수를 조정할 수 있게 합니다:

  • "active" (기본값)은 유휴 큐비트까지 박스를 확장하지 않습니다.
  • "active_accum" 회로 내의 이전 명령에 의해 이미 연산이 수행된 큐비트들로 모든 상자를 확장합니다. 이는 회로 시작 부분의 큐비트를 활성화될 때까지 회전시키지 않음으로써, 가능한 한 오랫동안 기저 상태에 머물게 하고 싶을 때 유용합니다.
  • "active_circuit" 회로 내의 어떤 명령어에 의해 연산이 수행되는 큐비트들까지 모든 상자를 확장합니다. 이는 반복되는 얽힘 층으로 구성된 회로에서, 각 박스마다 노이즈를 학습해야 하므로 고유한 박스의 수를 최소화하고자 할 때 유용합니다.
  • "all" 회로의 모든 양자 레지스터에 있는 모든 큐비트에 대해 모든 박스를 확장합니다. 이는 QPU 내의 모든 큐비트가 항상 트위얼링 상태를 유지하도록 하고자 할 때 "active_circuit" , 이에 대한 확장으로 유용합니다.

다음 예제에서는 각 전략을 기본 회로에 적용한 후, 그 결과를 도식으로 나타냅니다.

circuit = QuantumCircuit(5, 2)
circuit.h(range(4))
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
circuit.barrier()
circuit.h(range(4))
circuit.measure([1, 2], [0, 1])

circuit.draw("mpl", scale=0.6)
../_images/cdf089891dabe1650f1303c8c747aa8cf03cdde4dfc42c772fe2264bd7a49a1b.png
import matplotlib.pyplot as plt

plt.figure(figsize=(9, 6))
for idx, strategy in enumerate(["active", "active_accum", "active_circuit", "all"]):
    ax = plt.subplot(2, 2, idx + 1)
    pm = generate_boxing_pass_manager(twirling_strategy=strategy, remove_barriers="never")
    transpiled_circuit = pm.run(circuit)
    fig = transpiled_circuit.draw("mpl", scale=0.8, ax=ax)
    ax.set_title(f"twirling_strategy='{strategy}'")

plt.tight_layout()
../_images/b810ecc4c65822cf60b3d652792a4089c5f931ad1e8320eccdd89bc50a08ba6d.png

장벽을 어떻게 처리할지 지정하십시오

기본적으로, 모든 얽힘 게이트와 측정 명령이 지시에 따라 상자에 담긴 후( twirling_strategy 선택으로 인한 확장 부분 포함), 가능한 경우 바로 오른쪽에 있는 단일 큐비트 게이트가 상자에 추가되기 전에 회로에서 장벽이 제거됩니다.

예를 들어, 다음 회로에는 배리어가 포함되어 있습니다:

circuit_with_barrier = QuantumCircuit(4)
circuit_with_barrier.h(range(4))
circuit_with_barrier.cz(0, 1)
circuit_with_barrier.barrier()
circuit_with_barrier.cz(2, 3)
circuit_with_barrier.measure_all()

circuit_with_barrier.draw("mpl", scale=0.8)
../_images/f2343807597155ab5301205803954b95d29ba0d7370440bd861439fd83d1a193.png

기본 동작 방식은 두 개의 얽힘 게이트가 같은 상자에 들어가는 것을 방지하지만, 단일 큐비트 게이트의 경우 장벽이 있음에도 불구하고 다음에 사용 가능한 상자로 흡수되도록 허용합니다.

boxing_pass_manager = generate_boxing_pass_manager()
transpiled_circuit = boxing_pass_manager.run(circuit_with_barrier)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/7e0812ac6b3f2405c765338ab25c2e9179165a7257ef1d996bea99f94cb39ca6.png

를 로 remove_barriers 설정하면 장벽이 'never' 유지되어 단일 큐비트 게이트에 제약이 가해집니다.

boxing_pass_manager = generate_boxing_pass_manager(remove_barriers="never")

transpiled_circuit = boxing_pass_manager.run(circuit_with_barrier)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/6b57e625509dd8ca55fbd96994398b03ac2fe6f76f21535db9bd042d4c68c987.png

마지막으로, 장벽을 즉시 제거하면 얽힌 입자들은 더 이상 서로 다른 상자에 들어가야만 하는 제약을 받지 않게 됩니다.

boxing_pass_manager = generate_boxing_pass_manager(remove_barriers="immediately")

transpiled_circuit = boxing_pass_manager.run(circuit_with_barrier)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/9a44c59a05a44a3e8f0ce9b7edd3ccc2896c6a68fb00ed110a7e225f52a7ca73.png

계층화의 원리

복싱 패스 관리자는 두 가지 주요 패스를 순차적으로 실행합니다:

  1. GroupGatesIntoBoxes — 얽혀 있는 게이트를 상자로 분류합니다. 이 단계에서는 단일 큐비트 게이트는 고려하지 않고, 오직 2큐비트 게이트만 그룹화합니다.
  2. AbsorbSingleQubitGates — 각 단일 큐비트 게이트를 그 오른쪽에서 가장 가까운 적격 상자로 흡수합니다.

계층화 과정에서, 회로 DAG를 위상 순서대로 GroupGatesIntoBoxes 순회하며, 각 2-큐비트 게이트를 큐비트가 아직 할당되지 않은 가장 이른 그룹에 배치한다. 다음과 같은 세 가지 종류의 명령어는 큐비트에 대한 현재 그룹을 비우는 구분자 역할을 하여, 해당 큐비트에 적용되는 후속 게이트들을 새로운 그룹으로 강제 이동시킵니다:

  • 장벽
  • 기존 상자 사용 설명서
  • 수치

단일 큐비트 게이트는 구분자가 아닙니다. 즉, 그룹화에 아무런 영향을 미치지 않으며, 그룹화 AbsorbSingleQubitGates 처리는 에 맡겨집니다. 현재는 교환법칙 분석이 수행되지 않으며, 그룹화는 회로의 위상적 순서를 있는 그대로 따릅니다.

왜 권장되는 remove_barriers="after_stratification" 기본값이

기본 모드는 입니다. 이는 두 가지 장점을 모두 갖추고 있기 때문입니다 "after_stratification" :

  • 장벽은 얽힘 게이트가 어떻게 그룹화되는지를 제한합니다(이 장벽들은 계층화 과정에서 구분선 역할을 합니다).
  • 실행 AbsorbSingleQubitGates 전에 장벽이 제거되므로, 단일 큐비트 게이트는 여전히 이전 장벽 위치들을 통과하여 가장 가까운 상자로 흡수될 수 있습니다.

대조적으로,

  • "never" 전체 회로에 장벽을 유지함으로써, 단일 큐비트 게이트를 장벽과 상자 사이에 가두어 흡수되는 것을 막고, 회로 내에 꼬이지 않은 회전 상태를 남기게 됩니다.
  • "immediately" 계층화 전에 장벽을 제거하므로, 그룹핑에 아무런 영향을 미치지 않습니다.
  • "finally" 이는 출력 회로에 장벽을 설정하고자 할 때(예: 시각화를 위해) 유용하지만, 장벽과 박스 사이의 단일 큐비트 게이트는 흡수되지 않습니다.

배리어형 박스 ISA 회로

반복적인 구조를 가진 회로 — 예를 들어 트로터화 해밀토니안 시뮬레이션, 변분적 가정, 오차 증폭 시퀀스 등 — 은 일반적으로 프로그래밍 방식으로 구축된 후 ISA 형식으로 변환됩니다. 트랜스파일된 회로에 상자를 수동으로 추가하는 것은 번거로우므로, 일반적인 작업 흐름은 다음과 같습니다:

  1. 상자 경계가 되도록 원하는 층 경계에 장벽을 삽입하여 논리 회로를 구성하십시오.
  2. ISA 회로로 변환합니다. Qiskit의 트랜스파일러는 라우팅 및 최적화 과정을 거치면서도 배리어를 유지합니다.
  3. ISA 서킷에서 generate_boxing_pass_manager() 경주를 펼치다.

한 층의 끝 부분이 모든 큐비트를 덮지 못할 때는 배리어가 필요합니다. 그렇지 않으면 탐욕적 알고리즘은 다음 계층의 게이트를—그 “여유” 큐비트들에—같은 그룹에 배치하게 될 것입니다. 구체적인 예로, 5-큐비트 링에서 수행되는 2단계 하이젠베르크 ZZ 시뮬레이션을 생각해 보자. 트로터 단계마다 세 가지 결합 층이 있습니다: 짝수 결합 (0,1), (2,3), 홀수 결합 (1,2), (3,4), 그리고 랩 결합입니다 (4,0). 홀수 결합 층이 지나간 후, 큐비트 0과 4는 모두 자유 상태가 된다. 장벽이 없으면, 랩 본드는 해당 자유 큐비트를 사용하는 다음 트로터 단계의 결합들과 탐욕적 그룹화(greedy grouping)를 (4,0) 형성하게 되어, 같은 상자 안에 서로 다른 단계의 혼합 게이트가 섞이게 됩니다.

from qiskit.circuit import Parameter, QuantumCircuit

n = 5  # 5-qubit ring: bonds (0,1), (1,2), (2,3), (3,4), (4,0)
dt = Parameter("dt")
heisenberg = QuantumCircuit(n)

for step in range(2):
    # Layer 1: even bonds (0,1) and (2,3)
    for idx in range(0, n - 1, 2):
        heisenberg.rzz(dt, idx, idx + 1)
    heisenberg.barrier()
    # Layer 2: odd bonds (1,2) and (3,4) -- qubits 0 and 4 are now free
    for idx in range(1, n - 1, 2):
        heisenberg.rzz(dt, idx, idx + 1)
    heisenberg.barrier()
    # Layer 3: wrap bond (4,0) -- both qubits were free after layer 2
    heisenberg.rzz(dt, n - 1, 0)
    if step < 1:
        heisenberg.barrier()  # separates the two Trotter steps

heisenberg.measure_all()

heisenberg.draw("mpl", scale=0.7)
../_images/172fa55c9f02964fef32fc045a50b86971126be728602b3f1e4b2437df2580b7.png

다음 코드는 기본 장치의 기본 얽힘 생성기가 CX라고 가정하고, 회로를 ISA 형식으로 변환합니다. 이 장벽들은 트랜스필레이션 과정을 거친 후에도 유지되며, 출력 회로에서 계속 표시된다는 점에 유의하십시오.

from qiskit.transpiler import generate_preset_pass_manager

preset_pm = generate_preset_pass_manager(
    basis_gates=["rz", "sx", "cx"],
    coupling_map=[[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]],
    optimization_level=1,
)
isa_circuit = preset_pm.run(heisenberg)
isa_circuit.draw("mpl", scale=0.5, fold=200)
../_images/e9a3fbd6ab1a91051c5cd0273d92ecebc6ae8ebbc370c30bc55daee1fd28bab7.png

다음으로, ISA 회로에 복싱 패스 관리자를 적용합니다. 세 개의 본드 층은 각각 트로터 단계마다 별도의 상자로 처리됩니다.

boxing_pm = generate_boxing_pass_manager()
boxed_isa = boxing_pm.run(isa_circuit)
boxed_isa.draw("mpl", scale=0.5, fold=100)
../_images/b59e3c047264b3340d9af0f1ca74ad9f7d4c1705d4a5176e441346db9b678213.png

Samplomatic의 패스 관리자를 Qiskit 프리셋 패스 관리자에 통합합니다

아래 코드는 Qiskit 프리셋 패스 매니저에 generate_boxing_pass_manager() 를 통합하는 방법을 보여줍니다. 트랜스파일된 회로는 ISA이며 박스들을 포함하고 있습니다.

from qiskit.transpiler import generate_preset_pass_manager

preset_pass_manager = generate_preset_pass_manager(
    basis_gates=["rz", "sx", "cx"],
    coupling_map=[[0, 1], [1, 2]],
    optimization_level=0,
)
boxing_pass_manager = generate_boxing_pass_manager()

# Run the boxing pass manager after the scheduling stage
preset_pass_manager.post_scheduling = boxing_pass_manager

circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(0, 2)
circuit.measure_all()

transpiled_circuit = preset_pass_manager.run(circuit)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/fe943b034588a5354a87abcf51b8d805c36f4f2b30a73a39c5886bce9e156b04.png

이 패턴은 장벽 기반의 ISA 박싱 워크플로우와도 자연스럽게 결합됩니다. 복싱 패스 관리자는 원래 논리 회로의 배리어가 트랜스필레이션을 성공적으로 통과한 후, 스케줄링 후 단계로 실행되므로, 예상대로 계층화를 안내합니다.

preset_pm = generate_preset_pass_manager(
    basis_gates=["rz", "sx", "cx"],
    coupling_map=[[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]],
    optimization_level=1,
)
preset_pm.post_scheduling = generate_boxing_pass_manager()

boxed_heisenberg = preset_pm.run(heisenberg)
boxed_heisenberg.draw("mpl", scale=0.5, fold=100)
../_images/4905bf1df63cc83fa581ed006a93beb709be504a4f59fc7f663f4efde62da175.png

주석 확인 및 수정

자동 박스 지정 후에는 특정 박스에 적용된 주석을 확인하거나 조정하고 싶을 수 있습니다. 예를 들어, 노이즈 주입을 추가하거나, 주석을 제거하거나, 회전 그룹을 변경하는 경우 등입니다. Samplomatic은 이러한 목적을 위해 samplomatic.utils 일련의 유틸리티 함수를 제공합니다. 이들 모두 원본을 수정하지 않고 새로운 회로를 반환합니다.

extend_annotations() 회로 내의 모든 박스에 하나 이상의 주석을 추가합니다.

from samplomatic import InjectNoise, Twirl
from samplomatic.utils import extend_annotations

boxed = generate_boxing_pass_manager().run(circuit_with_barrier)

# Add InjectNoise to every box
with_noise = extend_annotations(boxed, InjectNoise("my_noise_ref"))
with_noise.draw("mpl", scale=0.8)
../_images/7e0812ac6b3f2405c765338ab25c2e9179165a7257ef1d996bea99f94cb39ca6.png

filter_annotations() 지정된 유형의 주석만 남기고 나머지는 제거합니다. replace_annotations() 각 어노테이션에 호출 가능 객체를 적용합니다. 이 호출 가능 객체는 해당 위치에 대체할 어노테이션 목록을 반환합니다(제거하려면 [] return을, 대체하려면 단일 요소 목록을, 확장하려면 다중 요소 목록을 반환합니다).

from samplomatic.utils import filter_annotations, replace_annotations

# Keep only Twirl annotations, drop everything else
twirl_only = filter_annotations(with_noise, Twirl)

# Replace the twirling group on every Twirl annotation
updated = replace_annotations(
    twirl_only, lambda a: [Twirl(group="local_c1")] if isinstance(a, Twirl) else [a]
)

이 범용 map_annotations() 함수는 주석 목록을 새로운 목록으로 매핑하는 모든 호출 가능 객체를 받아들이며, 이를 통해 상자별 변환을 완전히 제어할 수 있습니다. strip_annotations() 모든 상자에서 모든 어노테이션을 제거하는 편리한 래퍼입니다.

모든 게이트 박스에 InjectNoise 를 추가하는 것과 같은 대량 변경의 경우, 의 매개변수가 inject_noise_targets 가장 간결한 방법입니다 generate_boxing_pass_manager() . 이러한 유틸리티는 패스 관리자 매개변수로 처리할 수 없는, 박스별 선택적 편집 작업에 유용합니다.


회로 만들기

에서 생성된 모든 패스 매니저는 에 의해 템플릿/샘플렉스 쌍으로 성공적으로 변환될 수 있는 회로들을 반환합니다 generate_boxing_pass_manager()build() . 예를 들어, 다음 코드는 복싱 패스 관리자가 생성한 회로에 대해 해당 함수를 build() 호출합니다.

from samplomatic import build

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit)

template, samplex = build(transpiled_circuit)

트랜스파일된 모든 회로가 성공적으로 빌드될 수 있도록, 패스 관리자는 필요할 때 추가 박스를 포함시키는 방법을 알고 있습니다. 예를 들어, 측정되지 않은 큐비트로 끝나는 아래 회로를 생각해 보자 0.

circuit_with_unmeasured_qubit = QuantumCircuit(4, 3)
circuit_with_unmeasured_qubit.cz(0, 1)
circuit_with_unmeasured_qubit.cz(2, 3)
for qubit in range(4):
    circuit_with_unmeasured_qubit.rz(Parameter(f"th_{qubit}"), qubit)
    circuit_with_unmeasured_qubit.rx(Parameter(f"phi_{qubit}"), qubit)
    circuit_with_unmeasured_qubit.rz(Parameter(f"lam_{qubit}"), qubit)
circuit_with_unmeasured_qubit.measure(range(1, 4), range(3))

circuit_with_unmeasured_qubit.draw("mpl", scale=0.8)
../_images/0452779799470d2deb4d32ce19f5aa28dfe8055a064e67c0e8e5684389845b0f.png

게이트와 측정값 주위에 왼쪽 방향 상자를 그릴 경우 0, 큐비트에 수집되지 않은 가상 게이트가 포함된 회로가 생성되며, 이 회로에 대해 build() 를 호출하면 오류가 발생합니다. 이를 방지하기 위해, 에서 반환된 패스 관리자들은 수집기 역할을 하는 오른쪽 정렬 상자를 추가할 generate_boxing_pass_manager() 수 있습니다. 예를 들어, 다음 코드에서 qubit은 수집되지 않은 가상 게이트를 포착하는 오른쪽 방향 상자로 종료됩니다 0 . 결과 회로의 깊이를 최소화하기 위해, 큐비트 에 작용하는 단일 큐비트 게이트들도 상자 안에 배치됩니다 0 .

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit_with_unmeasured_qubit)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/711ee3c014edf6f70ede5dfa849494286e96870b3bd70a2a89f687d83cc5bfc1.png

또 다른 예로, 박스화되지 않은 측정값으로 인해 수집되지 않을 수 있는 가상 게이트를 수집하기 위해 ‘right-dressed’ 박스가 추가됩니다.

boxing_pass_manager = generate_boxing_pass_manager(
    enable_gates=True,
    enable_measures=False,
)
transpiled_circuit = boxing_pass_manager.run(circuit_with_unmeasured_qubit)
transpiled_circuit.draw("mpl", scale=0.8)
../_images/d59d0c0af3c47f474a964a455533b99e09a65364454ec04ced7581e6afac73ab.png
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.