실행기의 입력과 출력
이 페이지의 코드는 다음 요구 사항을 바탕으로 개발되었습니다. 이 버전 이상을 사용하시기를 권장합니다.
qiskit[all]~=2.5.2 qiskit-ibm-runtime~=0.47.0 samplomatic~=0.21.0
Executor 기본 요소는 방향성 실행 모델의 일부로, 오류 완화 워크플로를 사용자 정의할 때 더 큰 유연성을 제공합니다.
Executor 기본 요소의 입력과 출력은 Sampler 및 Estimator 기본 요소의 입력과 출력과 매우 다릅니다. 예를 들어, Executor는 펍(PUB) 목록을 입력으로 받는 대신, 객체 목록을 QuantumProgramItem 포함하는 객체를 QuantumProgram입력으로 받습니다. 이러한 컨테이너 클래스는 단순한 튜플 데이터 구조인 PUB 보다 더 큰 유연성을 제공합니다.
QuantumProgramItem``QuantumProgramResult실행자의 출력은 이며, 이는 반복 가능한 객체로, 각 입력에 대해 하나의 요소를 포함합니다.
입력: 양자 프로그램
앞서 언급했듯이, Executor 기본 객체의 입력은 객체들의
QuantumProgramItem 반복 가능한 집합인QuantumProgram 입니다. 이러한 객체는 두 가지 유형으로 나눌 수 있습니다:
CircuitItem, 일반적으로 회로와 해당 매개변수 값(있는 경우)을 저장합니다.SamplexItem, 일반적으로 다음 내용을 저장합니다:- 회로 도면
- 런타임 시 무작위 매개변수 집합을 생성하는 데 사용되는 샘플렉스 객체(예: 트위링 수행 또는 노이즈 주입)
- samplex에 전달되는 인자들로, 여기에는 원래 회로의 매개변수 값이 포함될 수 있습니다
이 항목들은 각각 집행자가 수행해야 할 서로 다른 업무를 나타냅니다.
시작하기 전에
samplex이 페이지의 일부 코드 예제에서는 Samplomatic 패키지의 일부인 를 사용합니다. 따라서, 해당 코드 블록을 실행하기 전에 다음 코드 블록에 표시된 대로 Samplomatic을 설치해야 합니다. 자세한 내용은 Samplomatic 설명서를 참조하십시오.
pip install samplomatic
# For visualization support, include the visualization dependencies.
# pip install samplomatic[vis]QuantumProgram 예시: 두 가지 다른 작업이 포함된 만들기
먼저 양자 프로그램을 초기화한 다음, 다음 예시와 같이 또는 append_samplex_item (samplex가 있는 경우)를 append_circuit_item 사용하여 프로그램 항목을 추가하십시오.
다음 셀은 를 QuantumProgram 초기화하고, 프로그램 내 각 항목의 모든 구성에 대해 1024회의 시뮬레이션을 실행하도록 지정합니다.
Sampler와 달리, 는 QuantumProgram 단 하나의 샷 값만 사용합니다. QuantumProgram다른 샷 값을 원하신다면 별도의 작업이 필요하며, 이는 별도의 작업으로 처리됩니다.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from qiskit_ibm_runtime import Executor, QiskitRuntimeService
from qiskit.circuit import Parameter, QuantumCircuit
import numpy as np
from samplomatic import build
from samplomatic.transpiler import generate_boxing_pass_manager
# Initialize an empty program
program = QuantumProgram(shots=1024)
# Initialize and transpile a 3-qubit quantum circuit with 2 parameters.
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.rz(Parameter("theta"), 0)
circuit.rz(Parameter("phi"), 1)
# `measure_all` adds a 3-bit classical register named "meas"
circuit.measure_all()
# Choose the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Generate a preset pass manager
# This will be used to convert the abstract circuit to an
# equivalent Instruction Set Architecture (ISA) circuit.
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=0
)
# Transpile the circuit
isa_circuit = preset_pass_manager.run(circuit)추가하기 CircuitItem
QuantumProgram다음으로, 백엔드의 명령어 집합 아키텍처(ISA)에 따라 트랜스파일된 대상 회로를.에 추가합니다. 이 회로에는 두 개의 매개변수가 있으므로, 매개변수 값도 함께 지정해야 합니다(이 예시에서는 10세트). 이 CircuitItem 코드를 실행하는 것이 프로그램이 수행할 첫 번째 작업입니다.
# Append the transpiled circuit and an array
# containing 10 sets of parameter values to the program
program.append_circuit_item(
isa_circuit,
circuit_arguments=np.random.rand(
10, 2
), # 10 sets of parameter values and 2 parameters
)추가하기 SamplexItem
회로 항목들은 어떠한 무작위화 과정도 없이 실행됩니다. 반대로, 샘플렉스 항목은 내용을 무작위로 배열하는 방식을 직접 지정할 수 있게 해줍니다. 다음 셀에서는 함수를 generate_boxing_pass_manager() 사용하여 회로의 게이트와 측정값을 상자로 묶고, 각 상자에 회전하는 주석을 추가합니다. 그런 다음 해당 build() 함수를 사용하여 템플릿 회로와 샘플렉스 쌍을 생성합니다.
이 SamplexItem 작업을 실행하는 것이 프로그램이 수행할 두 번째 작업입니다.
및 그 인자에 대한 samplex 자세한 내용은 Samplomatic API 문서를 참조하십시오. 함수 generate_boxing_pass_manager() 사용법에 대한 자세한 내용은 Samplomatic Transpiler 가이드를 참조하십시오.
# Transpile the circuit, additionally grouping gates and measurements into annotated boxes
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=0
)
# Use the boxing pass manager to group gates
# and measurements into boxes and add
# a`Twirl` annotation.
preset_pass_manager.post_scheduling = generate_boxing_pass_manager(
# Add gate twirling
enable_gates=True,
# Add measurement twirling
enable_measures=True,
)
boxed_circuit = preset_pass_manager.run(circuit)
# Build the template circuit and the samplex. The template circuit has parametric gates
# without fixed values and the samplex randomly generates the parameter
# values on the server side at runtime to perform twirling.
template_circuit, samplex = build(boxed_circuit)
# Determine what arguments are required by the samplex.
# Input the arguments in samplex_arguments.
print(samplex.inputs())Output:
TensorInterface(<
- 'parameter_values' <float64[2]>: Input parameter values to use during sampling.
>)
# Append the template circuit and samplex as a samplex item
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
# the arguments required by the samplex.sample method
"parameter_values": np.random.rand(10, 2),
},
shape=(28, 10), # 28 randomizations and 10 sets of parameter values
)# Initialize an Executor with the default options
executor = Executor(mode=backend)
# Submit the job
job = executor.run(program)
# Retrieve the result
result = job.result()출력
QuantumProgramResultExecutor의 출력값은 반복 가능한 객체인 입니다. 입력 QuantumProgramItem 항목 하나당 하나의 항목이 포함되며, 입력 항목과 동일한 순서로 정렬되어 있습니다. 이러한 각 출력 항목은 사전(dictionary) 형태로, 키는 입력 회로(그 밖의 요소들 포함)에 있는 기존 레지스터의 이름에 해당하는 문자열입니다. 따라서 샘플러 출력에서 그랬던 것처럼 더 이상 이러한 이름을 외울 필요가 없습니다. np.ndarray사전 값의 데이터 형식은 입니다.
이전 예제의 결과에는 다음 항목들이 포함되어 있습니다:
CircuitItem개의 결과
CircuitItem첫 번째 항목에는 프로그램의 첫 번째 작업(a)을 실행한 결과가 포함되어 있습니다. 여기에는 입력 회로의 클래식 레지스터 이름인 단일 meas 키가 포함되어 있습니다. (parameter sets, shots, register bits)이 키의 값은 형식의 배열에 np.ndarray 매핑되며, 위 예제의 경우 (10, 1024, 3)입니다.
다음 코드는 이 정보에 접근하는 방법을 보여줍니다:
# Access the results of the classical register of task #0, a CircuitItem
result_0 = result[0]["meas"]
print(f"Result shape: {result_0.shape}")Output:
Result shape: (10, 1024, 3)
SamplexItem개의 결과
SamplexItem두 번째 항목에는 프로그램의 두 번째 작업(a)을 실행한 결과가 포함되어 있습니다. 이 항목에는 여러 개의 키가 포함되어 있습니다. 'key'는 meas 입력 회로의 클래식 레지스터 이름이며, 해당 레지스터의 결과 배열에 매핑됩니다. (randomizations, parameter sets, shots, classical bits)이 배열의 차원은 이 예시에서 (28, 10, 1024, 3)입니다. 또한, 출력값에는 레지스터에 meas 대한 측정 왜곡을 보정하기 위한 비트 반전 보정값을 나타내는 key가 measurement_flips.meas 포함되어 있습니다. 이 예제의 경우 비트 반전을 수행하는 데 단 한 번의 연산만 필요하므로, 출력 형식은 (28, 10, 1, 3)이 됩니다.
# Access the results of the classical register of task #1
result_1 = result[1]["meas"]
print(f"Result shape: {result_1.shape}")
# Access the bit-flip corrections
flips_1 = result[1]["measurement_flips.meas"]
print(f"Bit-flip corrections shape: {flips_1.shape}")
# Undo the bit flips via classical XOR
unflipped_result_1 = result_1 ^ flips_1Output:
Result shape: (28, 10, 1024, 3)
Bit-flip corrections shape: (28, 10, 1, 3)
다음 단계
- Executor를 사용한 예제를 살펴보세요.
- 지시형 실행 모델 에 대해 알아보세요.
- Executor 브로드캐스팅을 이해합니다.