Skip to main content
IBM Quantum Platform

동적 회로 실행

동적 회로는 양자 회로 실행 도중에 큐비트를 측정하고, 그 중간 측정 결과를 바탕으로 회로 내에서 고전 논리 연산을 수행할 수 있게 해주는 강력한 도구입니다. 이 과정을 고전적 피드포워드라고도 합니다. 동적 회로를 가장 효과적으로 활용하는 방법을 파악하는 단계는 아직 초기 단계이지만, 양자 연구계에서는 이미 다음과 같은 여러 가지 활용 사례를 제시하고 있습니다:

그러나 동적 회로가 가져다주는 이러한 개선점에는 상응하는 단점이 따릅니다. 회로 중간 측정 및 고전적 연산은 일반적으로 2-큐비트 게이트보다 실행 시간이 더 길며, 이러한 시간 증가는 회로 깊이가 줄어드는 이점을 상쇄할 수도 있다. 따라서, IBM Quantum® 가 새로운 버전의 동적 회로를 출시함에 따라, 회로 중간 측정 시간을 단축하는 것이 개선의 중점 분야로 꼽히고 있습니다. 동적 회로를 사용할 때 적용되는 기타 제한 사항에 대해서는 ‘추정기(Estimator)’ 또는 ‘샘플러(Sampler)’ 기능 호환성 표를 참조하십시오.

OpenQASM 3 사양 에서는 여러 가지 제어 흐름 구조를 정의하고 있지만, IBM Quantum Compute Service는 현재 if 조건문만 지원합니다. Qiskit SDK 에서 이는 QuantumCircuit 의 if_test 메서드에 해당합니다. 이 메서드는 컨텍스트 매니저 를 반환하며, 일반적으로 with 문에서 사용됩니다. 이 안내서에서는 이 조건문을 사용하는 방법을 설명합니다.

Note

이 가이드의 코드 예제에서는 회로 중간 지점 측정을 위해 표준 측정 명령어를 사용합니다. 단, 백엔드에서 지원하는 경우 대신 해당 MidCircuitMeasure 명령어를 사용하는 것이 좋습니다. 자세한 내용은 ‘회로 중간 측정’ 섹션을 참조하십시오.

  • 이 페이지의 코드는 다음 요구 사항을 바탕으로 개발되었습니다. 이 버전 이상을 사용하시기를 권장합니다.

    qiskit[all]~=2.6.1
    qiskit-ibm-runtime~=0.50.0
    

동적 회로를 지원하는 백엔드 찾기

계정에서 액세스할 수 있고 동적 회로를 지원하는 모든 백엔드를 찾으려면 다음과 같은 코드를 실행하세요. 이 예제는 사용자가 로그인 정보를 저장해 두었다고 가정합니다. IBM Quantum Compute Service 계정을 초기화할 때 자격 증명을 명시적으로 지정할 수도 있습니다. 이를 통해 예를 들어 특정 인스턴스나 요금제 유형에서 사용할 수 있는 백엔드를 확인할 수 있습니다.

참고
  • 계정에서 사용할 수 있는 백엔드는 자격 증명에 지정된 인스턴스에 따라 달라집니다.
  • 모든 백엔드에서 모든 사용자가 동적 회로의 새 버전을 이용할 수 있게 되었습니다. 자세한 내용은 공지사항을 확인해 주세요.
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
dc_backends = service.backends(dynamic_circuits=True)
print(dc_backends)

Output:

[<IBMBackend('ibm_boston')>, <IBMBackend('ibm_fez')>, <IBMBackend('ibm_kingston')>, <IBMBackend('ibm_marrakesh')>, <IBMBackend('ibm_phoenix')>, <IBMBackend('ibm_pittsburgh')>]

회로 중간 측정

v0.43.0qiskit-ibm-runtime 가 도입되기 전에는 Qiskit에서 유일한 측정 명령어였습니다 measure . 그러나 회로 중간에서의 측정은 단자 측정(회로 끝단에서 이루어지는 측정)과는 다른 조정 조건이 필요합니다. 예를 들어, 회로 중간 지점에서의 측정을 조정할 때는 명령어 실행 시간을 고려해야 합니다. 명령어 실행 시간이 길어질수록 회로의 잡음이 증가하기 때문입니다. 단말 측정 후에는 명령어가 없기 때문에, 단말 측정 시 명령어 실행 시간을 고려할 필요가 없습니다.

Note

이 MidCircuitMeasure 명령어는 백엔드의 supported_instructions. 파일에 보고된 measure_2 명령어와 일치합니다. 그러나 는 모든 백엔드에서 지원되지 않습니다 measure_2 . 를 사용하여 이를 service.backends(filters=lambda b: "measure_2" in b.supported_instructions) 지원하는 백엔드를 찾으세요. 향후 새로운 측정 항목이 추가될 수도 있으나, 이는 보장되지 않습니다.

MidCircuitMeasure 메소드

v0.43.0qiskit-ibm-runtime 에서 해당 MidCircuitMeasure 명령어가 도입되었습니다. 이름에서 알 수 있듯이, 이는 ‘ IBM® ’ QPU의 회로 중간 단계에 최적화된 새로운 측정 명령어입니다. 회로 중간 지점 측정에 QuantumCircuit.measure 를 사용할 수는 있지만, 설계상 MidCircuitMeasure 가 일반적으로 더 나은 선택입니다. 예를 들어, 이는 을 사용할 때보다 회로에 가해지는 QuantumCircuit.measure 부하가 적습니다.

from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime.circuit import MidCircuitMeasure

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

circ = QuantumCircuit(2, 2)
circ.x(0)
circ.append(MidCircuitMeasure(), [0], [0])
# circ.measure([0], [0])
# circ.measure_all()
print(circ.draw(cregbundle=False))

Output:

     ┌───┐┌────────────┐
q_0: ┤ X ├┤0           ├
     └───┘│            │
q_1: ─────┤  Measure_2 ├
          │            │
c_0: ═════╡0           ╞
          └────────────┘
c_1: ═══════════════════
                        
중요한 참고사항
  • 측정 기능을 사용하려면 클래식 레지스터가 적어도 하나 있어야 합니다.
  • Sampler 프리미티브는 회로 측정이 필요합니다. Estimator 프라이머리타이를 사용하여 회로 측정값을 추가할 수는 있지만, 이러한 측정값은 무시됩니다.

Store

0.47.0 버전 이상에서는 qiskit-ibm-runtime , 특정 수식 결과를 반복적으로 사용할 경우 해당 수식의 결과를 저장하기 위해 명령을 store 사용할 수 있습니다. 작업이 자동으로 병렬화되어, 실행 시 코드의 효율성이 크게 향상됩니다.

자세한 내용은 ‘고전적 피드포워드 및 제어 흐름’ 가이드를 참조하십시오.

Note

실제 백엔드에서 를 사용하여 store 클래식 레지스터에 값을 저장할 경우, 해당 값은 실행 중에 메모리에만 저장되며, 작업 결과에 복사되거나 반환되지는 않습니다.

예를 들어, 다음 코드에서 는 실행 중에 와 creg 동일한 값을 가지며, temp 는 if_test 예상대로 작동합니다. creg하지만 작업이 완료된 후, 작업 결과에 반환된 tempBitArray 에는 값이 포함되어 있지 않습니다. 0즉, job.result()[0].data.temp 는 이다.

creg = ClassicalRegister(3, "c")
temp = ClassicalRegister(3, "temp")
...
qc.store(temp, creg)
with circuit.if_test((temp, 0b001)):
    ...

전체 예시

다음 코드는 IBM® 하드웨어에서 동적 회로를 생성하고 실행합니다.

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.transpiler import generate_preset_pass_manager

# Legacy server-side primitive before qiskit-ibm-runtime v0.50.0
# from qiskit_ibm_runtime import Sampler

# Client-side primitive introduced in qiskit-ibm-runtime v0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler

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

# Create a dynamic circuit

qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
qc = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits

qc.h(q0)
qc.measure(q0, c0)
with qc.if_test((c0, 1)):
    qc.x(q0)
qc.measure(q0, c0)


# Convert to an ISA circuit for the given backend

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)

# Generate samplers for backend targets
sampler = Sampler(backend)

# Submit jobs
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()

print(
    f">>> {' Job ID:':<10}  {sampler_job.job_id()} ({sampler_job.status()})"
)

Output:

>>>  Job ID:    dbjeaj0nceqs73ajs65g (DONE)

양자 컴퓨팅의 한계

Quantum Compute에서 동적 회로를 실행할 때는 다음 제약 사항을 유의하십시오.

  • 제어 전자 장치의 물리적 메모리 용량이 제한적이기 때문에, 명령어의 if 수와 그 피연산자의 크기에도 제한이 있습니다. 이 제한은 작업(회로가 아님) 내의 브로드캐스트 횟수와 브로드캐스트된 비트 수에 따라 결정됩니다.

    특정 if 조건을 처리할 때는 해당 평가를 수행하기 위해 측정 데이터를 제어 로직으로 전송해야 합니다. 브로드캐스트란 고유한 고전적 데이터의 전송을 의미하며, 브로드캐스트 비트란 전송되는 고전적 비트의 수를 말합니다. 다음을 고려하십시오.

    c0 = ClassicalRegister(3)
    c1 = ClassicalRegister(5)
    ...
    with circuit.if_test((c0, 1)) ...
    with circuit.if_test((c0, 3)) ...
    with circuit.if_test((c1[2], 1)) ...

    앞서 소개한 코드 예제에서, 의 처음 두 if_test 객체는 하나의 c0 브로드캐스트로 간주됩니다. 이는 의 내용이 c0 변경되지 않았기 때문에 재전송할 필요가 없기 때문입니다. 이 if_test 방송은 c1 재방송입니다. 첫 번째는 세 비트를 모두 c0 전송하고, 두 번째는 단 한 비트만 전송하므로, 총 네 비트가 전송됩니다.

    현재, 매번 60비트를 전송할 경우, 해당 작업에는 약 300회의 전송이 포함될 수 있습니다. 하지만 매번 1비트씩만 전송한다면, 이 작업에는 총 2400회의 전송이 필요할 수 있습니다.

  • 문에서 if_test 사용되는 피연산자는 32비트 이하여야 합니다. 따라서 전체를 비교하는 ClassicalRegister 경우, 그 크기는 ClassicalRegister 32비트 이하여야 합니다. 하지만 a의 단일 비트 하나만을 ClassicalRegister 비교하는 경우, 그 크기는 어떤 ClassicalRegister 크기라도 될 수 있습니다(피연산자가 단 1비트뿐이기 때문입니다).

    예를 들어, "Not valid" 코드 블록은 가 32비트보다 크기 cr 때문에 작동하지 않습니다. 그러나 “Valid” 코드 블록에서 볼 수 있듯이, 비트 하나만 테스트하는 경우에는 32비트보다 더 넓은 클래식 레지스터를 사용할 수 있습니다.

       cr = ClassicalRegister(50)
       qr = QuantumRegister(50)
       circuit = QuantumCircuit(qr, cr)
       ...
       circ.measure(qr, cr)
       with circ.if_test((cr, 15)):
          ...
  • 중첩된 조건문은 허용되지 않습니다. 예를 들어, 다음 코드 블록은 태그 안에 if_test 태그가 포함되어 if_test있어 작동하지 않습니다:

       c1 = ClassicalRegister(1, "c1")
       c2 = ClassicalRegister(2, "c2")
       ...
       with circ.if_test((c1, 1)):
        with circ.if_test(c2, 1)):
         ...
  • 조건문 내부에 or 연산자나 reset 측정값을 사용하는 것은 지원되지 않습니다.

  • 산술 연산은 지원되지 않습니다.

  • OpenQASM 3 기능 표를 참조하여 Qiskit 및 Quantum Compute에서 지원되는 OpenQASM 3 기능이 무엇인지 확인하십시오.

  • IBM Quantum 프리미티브에 회로를 전달하기 위한 입력 형식으로 OpenQASM 3( 대신 QuantumCircuit)을 사용할 경우, Qiskit에 로드할 수 있는 명령어만 지원됩니다. 예를 들어, 클래식 연산은 Qiskit에 불러올 수 없기 때문에 지원되지 않습니다. 자세한 내용은 “ OpenQASM s 3 프로그램을 Qiskit으로 가져오기 ”를 참조하십시오.

  • , while, 및 switch for명령어는 지원되지 않습니다.


Estimator와 함께 동적 회로 사용

Estimator는 동적 회로를 지원하지 않으므로, 대신 Sampler를 사용하여 직접 측정 회로를 구성할 수 있습니다.

Estimator의 동작을 재현하려면 다음 절차를 따르십시오:

  1. 모든 관측 가능한 변수의 항들을 하나의 파티션으로 묶는다. 예를 들어, 를 PauliList API사용하면 됩니다.
    Note

    BitArray 'primitive' 속성을 사용하여 주어진 관측량의 기대값을 계산할 수 있습니다.

  2. 각 파티션에 대해 하나의 기저 변환 회로를 실행합니다(각 파티션에 필요한 기저 변환을 수행합니다). 자세한 내용은 ‘측정 기준’ 애드온 유틸리티를 measurement_bases 모듈 참조하십시오. 자세한 내용은 Qiskit 애드온 유틸리티 패키지의 설명서를 참조하십시오.
  3. 각 파티션의 결과를 다시 합산하십시오.

제한사항

동적 회로를 사용할 때의 제한 사항을 파악하려면 기능 호환성 표를 확인하십시오. 기능 호환성은 기본형에 의존하지 않는다는 점에 유의하십시오.


다음 단계

권장사항
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.