스트레치를 사용한 지연된 타이밍 해결
OpenQASM 의 3 언어 사양에는 절대적인 타이밍 대신 상대적인 타이밍을 지정할 수 있는 type stretch 이 포함되어 있습니다. Qiskit v2.0.0 에서 duration 형식의 Delay duration stretch 에 대한 지원이 추가되었습니다. 스트레치 지속 시간의 구체적인 값은 보정된 게이트의 정확한 지속 시간이 알려진 후 컴파일 시점에 해결됩니다. 컴파일러는 하나 이상의 큐비트에 대한 타이밍 제약 조건 하에서 스트레치 지속 시간을 최소화하려고 시도합니다. 그런 다음 정확한 타이밍을 알지 못해도 다음과 같은 게이트 설계를 표현할 수 있습니다: 게이트를 균일하게 간격 배치하기(예: 고차 에코 디커플링 시퀀스 구현), 게이트 시퀀스를 왼쪽 정렬하기, 또는 일부 하위 회로 동안 게이트 적용하기.
예
동적 분리
stretch 의 일반적인 사용 사례는 다른 큐비트가 조건부 연산을 수행하는 동안 유휴 큐비트에 동적 디커플링을 적용하는 것입니다.
예를 들어, 다음 그림과 같이 stretch 을 사용하여 큐비트 0에 적용된 조건부 블록의 기간 동안 큐비트 1에 XX 동적 디커플링 시퀀스를 적용할 수 있습니다:
해당 회로는 다음과 같습니다. 이 상대적 타이밍의 경계를 정의하려면 한 쌍의 배리어가 필요하다는 점에 유의하세요.
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.circuit.classical import expr
qubits = QuantumRegister(2)
clbits = ClassicalRegister(2)
circuit = QuantumCircuit(qubits, clbits)
(q0, q1) = qubits
(c0, c1) = clbits
# Add barriers to define the boundaries
circuit.barrier()
circuit.h(q0)
circuit.measure(q0, c0)
with circuit.if_test((c0, 1)) as else_:
circuit.h(q0)
with else_:
circuit.x(q0)
# Apply an XX DD sequence with stretch on qubit 1
s = circuit.add_stretch("s")
circuit.delay(s, q1)
circuit.x(q1)
circuit.delay(expr.mul(s, 2), q1)
circuit.x(q1)
circuit.delay(s, q1)
circuit.barrier()일정 조정
이 예에서는 stretch 을 사용하여 두 장벽 사이의 게이트 시퀀스가 실제 길이와 상관없이 왼쪽으로 정렬되도록 합니다:
from qiskit import QuantumCircuit
from numpy import pi
qc = QuantumCircuit(5)
qc.barrier()
qc.cx(0, 1)
qc.u(pi/4, 0, pi/2, 2)
qc.cx(3, 4)
a = qc.add_stretch("a")
b = qc.add_stretch("b")
c = qc.add_stretch("c")
# Use the stretches as Delay duration.
qc.delay(a, [0, 1])
qc.delay(b, 2)
qc.delay(c, [3, 4])
qc.barrier()IBM Quantum Compute Service와 함께 stretch 사용할 때, 스트레치 처리 과정에서 발생하는 나머지 값은 해당 스트레치를 적용하는 첫 번째 지연 시간에 더해집니다.
예:
a = circuit.add_stretch("a")
circuit.barrier(q0, q1)
circuit.delay(100, q0)
circuit.delay(a, q1) # resolve to 26
circuit.x(q1) # duration: 8
circuit.delay(a, q1) # resolve to 25
circuit.x(q1) # duration: 8
circuit.delay(a, q1) # resolve to 25
circuit.x(q1) # duration: 8
circuit.barrier(q0, q1)위의 코드는 나머지 1을 제외한 25의 값으로 해석됩니다. 첫 번째 지연([a] )에 나머지가 추가됩니다.
스트레치 해상도 방정식:
IBM Quantum Compute Service에서 스트레치 값 보기
스트레치 지속 시간의 실제 값은 회로가 스케줄링된 후, 컴파일 시점에 결정됩니다. IBM Quantum Compute Service에서 샘플러 작업을 실행할 때, 작업 결과 메타데이터에서 해결된 스트레치 값을 확인할 수 있습니다. Quantum Compute에서 stretch 에 대한 지원은 현재 실험 단계이므로, 해당 데이터를 가져오려면 먼저 실험용 옵션을 설정한 다음, 다음과 같이 메타데이터에서 직접 데이터에 접근해야 합니다:
# Enable stretch value retrieval.
sampler.options.experimental = {
"execution": {
"stretch_values": True,
"scheduler_timing": True,
},
}
# Access the stretch values from the metadata.
job_result = job.result()
circuit_stretch_values = (
job_result[0].metadata["compilation"]["stretch_values"]
)
# Visualize the timing.
# Use the sliders at the bottom, the controls at the top, and the
# legend on the side of the output to customize the view.
draw_circuit_schedule_timing(ob.result()[0].metadata['compilation']
['scheduler_timing']['timing'])"컴파일" 메타데이터에는 전체 회로 실행 시간이 표시되지만, 이는 청구용 시간(QPU 시간)이 아닙니다.
메타데이터 출력을 이해하십시오
메타데이터는 stretch_values 다음 정보를 반환합니다:
- 이름: 적용된 스트레치의 이름.
- 값: 요청된 목표 값.
- 잔여값: 스트레치 해결 과정에서 발생한 잔여값으로, 해당 스트레치를 사용하는 첫 번째 지연에 추가됩니다.
- 확장된 값: 스트레치 시작점과 지속 시간을 지정하는 값 집합.
예
# Define the circuit
circuit = QuantumCircuit(4)
foo = circuit.add_stretch("foo")
bar = circuit.add_stretch("bar")
circuit.barrier()
circuit.cz(0, 1)
circuit.cz(0, 1)
circuit.cz(0, 1)
circuit.cz(0, 1)
circuit.delay(foo, 2)
circuit.x(2)
# 3*foo
circuit.delay(expr.mul(3, foo), 2)
circuit.x(2)
# 2*foo
circuit.delay(expr.mul(2, foo), 2)
circuit.delay(bar, 3)
circuit.x(3)
circuit.delay(bar, 3)
circuit.measure_all()메타데이터 출력
[{'name': 'bar',
'value': 29,
'remainder': 1,
'expanded_values': [[1365, 30], [1404, 29]]},
{'name': 'foo',
'value': 8,
'remainder': 2,
'expanded_values': [[1365, 10], [1384, 24], [1417, 16]]}
]기간에 대해 반환되는 값은 목표값과 계산된 잔여값에 따라 달라집니다. 예를 들어, foo에 대해 반환된 지속 시간은 다음과 같습니다:
foo value+remainder(8+2 = 10)foo value* 3 (8 × 3 = 24)foo value* 2 (8 × 2 = 16)
시각화를 활용하여 타이밍을 이해하고 확인할 수 있습니다.
draw_circuit_schedule_timing(job.result()[0].metadata
['compilation']['scheduler_timing']['timing'])다음 그림에서, 예시 출력에 기반하여, 는 큐비트 2의 foo 스트레치에 해당합니다. 첫 번째 스트레치 지연은 ( init_play 1365) foo 의 끝에서 시작됩니다. 스트레치 지속 시간은 10이므로, 해당 지연은 x 게이트가 시작될 때 종료됩니다(1365+10=1375). 두 번째와 세 번째 스트레칭도 비슷한 방식으로 해석할 수 있습니다.

하단의 슬라이더, 상단의 컨트롤(출력 이미지에 마우스를 올리면 표시됨), 그리고 출력물 옆의 범례를 사용하여 보기를 맞춤 설정하세요. 이미지에 마우스를 올려 정확한 데이터를 확인하세요.
자세한 내용은 ‘회로 타이밍 시각화’ 항목을 참조하십시오.
양자 컴퓨팅의 한계
Quantum Compute에서 stretch 에 대한 지원은 현재 실험 단계이며, 다음과 같은 제약 사항이 있습니다:
-
배리어(암시적 및 명시적) 사이에 설정된 큐비트당 최대 하나의 스트레치 변수만 사용할 수 있습니다. 큐비트 세트는 하나 이상의 큐비트로, 이러한 세트는 상호 배타적이어야 합니다.
a = circuit.add_stretch("a") b = circuit.add_stretch("b") circuit.delay(a, (q0, q1)) circuit.delay(b, q0) # Invalid because 2 stretches are applied on q0a = circuit.add_stretch("a") b = circuit.add_stretch("b") circuit.delay(a, (q0, q1)) circuit.delay(b, q2) -
일련의 장벽으로 둘러싸인 영역을 장벽 영역이라고 합니다. 스트레치 변수는 여러 장벽 영역에서 사용할 수 없습니다.
# Stretch a is used in two barrier regions a = circuit.add_stretch("a") circuit.barrier((q0, q1)) circuit.delay(a, q0) circuit.barrier((q0, q1)) circuit.delay(a, q0) circuit.barrier((q0, q1))stretch 함수의 잘못된 사용 # Stretch a is used inside a barrier region that is on q0 and q1 a = circuit.add_stretch("a") circuit.barrier((q0, q1)) circuit.delay(a, q0) circuit.barrier(q2) circuit.delay(a, q0) circuit.barrier((q0, q1))stretch 함수의 올바른 사용법 -
스트레치 표현식은
X및Y이 부동 소수점 또는 정수 상수인X*stretch + Y형식의 표현식으로 제한됩니다.a = circuit.add_stretch("a") b = circuit.add_stretch("b") c = circuit.add_stretch("c") # (a / b) * c is not supported circuit.delay(expr.mul(expr.div(a, b), c), q1)from qiskit.circuit import Duration a = circuit.add_stretch("a") circuit.delay(expr.add(expr.mul(a, 2), Duration.dt(3)), 0) -
스트레치 표현식에는 하나의 스트레치 변수만 포함할 수 있습니다.
a = circuit.add_stretch("a") b = circuit.add_stretch("b") circuit.delay(expr.add(a, b), 0)a = circuit.add_stretch("a") circuit.delay(expr.add(a, a), 0) -
스트레치 표현식은 음수 지연 값으로 해결할 수 없습니다. 현재 솔버는 음이 아닌 제약 조건을 추론하지 않습니다.
from qiskit.circuit import Duration circuit.barrier((q0, q1)) circuit.delay(20, q1) # The length of this barrier region is 20dt, meaning the # equation for solving stretch 'a' is a + 40dt = 20dt, giving a = -20dt. circuit.delay(expr.add(a, Duration.dt(40)), q0) circuit.barrier((q0, q1))circuit.barrier((q0, q1)) circuit.delay(20, q1) circuit.delay(a, q0) circuit.barrier((q0, q1))