Lumaktaw sa pangunahing nilalaman

Naantalang resolusyon ng timing gamit ang stretch

Ang OpenQASM 3 language specification ay naglalaman ng uri na stretch kung saan maaari kang tumukoy ng relatibong timing ng mga operasyon sa halip na absolute timing. Ang suporta para sa stretch bilang mga tagal para sa mga instruksyon na Delay ay idinagdag sa Qiskit v2.0.0. Ang konkretong halaga ng tagal ng stretch ay nareresolta sa compile time, pagkatapos malaman ang eksaktong tagal ng mga calibrated na Gate. Sinisikap ng compiler na i-minimize ang tagal ng stretch, batay sa mga hadlang sa timing ng isa o higit pang mga Qubit. Maaari ka na ring mag-ekspresa ng mga disenyo ng Gate tulad ng pantay na paglalagay ng mga Gate (halimbawa, para ipatupad ang mas mataas na antas ng echo decoupling sequence), pag-align sa kaliwa ng isang pagkakasunod-sunod ng mga Gate, o pag-apply ng Gate para sa tagal ng ilang sub-circuit, nang hindi alam ang eksaktong timing.

Mga Halimbawa​

Dynamical decoupling​

Ang isang karaniwang gamit ng stretch ay ang pag-apply ng dynamical decoupling sa isang Qubit na walang ginagawa habang ang isa pang Qubit ay sumasailalim sa mga kondisyonal na operasyon.

Halimbawa, maaari nating gamitin ang stretch para mag-apply ng XX dynamical decoupling sequence sa Qubit 1, para sa tagal ng kondisyonal na bloke na inilapat sa Qubit 0, gaya ng inilalarawan ng sumusunod na diagram:

Larawang nagpapakita ng sumusunod na circuit

Ang kaukulang Circuit ay magiging ganito. Tandaan na kailangan ng pares ng mga barrier para tukuyin ang mga hangganan ng relatibong timing na ito.

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()

Pag-align ng scheduling​

Ginagamit ng halimbawang ito ang stretch para matiyak na ang isang pagkakasunod-sunod ng mga Gate sa pagitan ng dalawang barrier ay naka-align sa kaliwa, anuman ang kanilang aktwal na mga tagal:

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()
tala

Kapag gumagamit ng stretch kasama ang Qiskit Runtime, ang anumang natitira mula sa resolusyon ng stretch ay idinadagdag sa unang delay na gumagamit ng stretch.

Halimbawa:

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)

Ang code sa itaas ay nareresolta sa halagang 25 na may natitira na 1. Ang unang delay[a] ay magkakaroon ng naidagdag na natitira.

Equation ng resolusyon ng stretch: a+8+a+8+a+8=100=3∗a+24a + 8 + a + 8 + a + 8 = 100 = 3*a + 24

Tingnan ang mga stretch value sa Qiskit Runtime​

Ang aktwal na halaga ng tagal ng stretch ay nareresolta sa compile time, pagkatapos ma-schedule ang Circuit. Kapag nagpapatakbo ng Sampler job sa Qiskit Runtime, maaari mong tingnan ang mga nareresoltang stretch value sa metadata ng resulta ng job. Ang suporta para sa stretch sa Qiskit Runtime ay experimental pa lang, kaya kailangan mo munang itakda ang isang experimental na opsyon para paganahin ang pagkuha nito, pagkatapos ay i-access ang data nang direkta mula sa metadata tulad ng sumusunod:

# 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'])
tala

Kahit na ang kabuuang oras ng Circuit ay ibinalik sa metadata ng "compilation", hindi ito ang oras na ginagamit para sa billing (quantum time).

Unawain ang output ng metadata​

Ang metadata ng stretch_values ay nagbabalik ng sumusunod na impormasyon:

  • Pangalan: Ang pangalan ng inilapat na stretch.
  • Halaga: Ang hiniling na goal value.
  • Natitira: Ang natitira mula sa paglutas ng stretch, na idinadagdag sa unang delay na gumagamit ng stretch.
  • Mga pinalawak na halaga: Mga set ng mga halaga na tumutukoy sa simula ng stretch at ang tagal nito.

Halimbawa​

# 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()

Output ng metadata​

 [{'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]]}
]

Ang mga halagang ibinalik para sa tagal ay nakasalalay sa goal value at sa kinakalkula na natitira. Halimbawa, ito ang mga tagal na ibinalik para sa foo:

  • foo value + remainder (8+2 = 10)
  • foo value * 3 (8 x 3 = 24)
  • foo value * 2 (8 x 2 = 16)

Maaari kang gumamit ng visualization para makatulong sa pag-unawa at pag-verify ng timing.

draw_circuit_schedule_timing(job.result()[0].metadata['compilation']['scheduler_timing']['timing'])

Sa sumusunod na larawan, batay sa halimbawang output, ang foo ay tumutugma sa mga stretch sa Qubit 2. Ang unang stretch delay na gumagamit ng foo ay nagsisimula sa dulo ng init_play (1365). Ang tagal ng stretch ay 10, kaya ang delay na iyon ay natatapos kapag nagsimula ang x Gate (1365+10=1375). Maaari mong bigyang-kahulugan ang pangalawa at ikatlong stretch sa katulad na paraan.

Ipinapakita ang output mula sa command na draw_circuit_schedule_timing.

Gamitin ang mga slider sa ibaba, ang mga kontrol sa itaas (i-hover ang iyong output na larawan para ipakita ang mga ito), at ang legend sa gilid ng output para i-customize ang view. I-hover ang larawan para makita ang eksaktong data.

Para sa buong detalye, tingnan ang paksa na Visualize circuit timing.

Mga limitasyon ng Qiskit Runtime​

Ang suporta para sa stretch sa Qiskit Runtime ay experimental pa lang at may mga sumusunod na hadlang:

  • Hindi hihigit sa isang stretch variable bawat qubit set sa pagitan ng mga barrier (implicit at explicit). Ang isang qubit set ay isa o higit pang mga Qubit; ang mga set na ito ay dapat na magkahiwalay.

    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 q0
  • Ang lugar na napapalibutan ng isang set ng mga barrier ay tinatawag na barrier region. Hindi maaaring gamitin ang stretch variable sa maraming barrier region.

    # 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))

    Ilustrasyon ng output ng nakaraang code

  • Ang mga stretch expression ay limitado sa mga may anyo na X*stretch + Y kung saan ang X at Y ay mga floating point o integer constant.

    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)
  • Ang mga stretch expression ay maaari lamang maglaman ng iisang stretch variable.

    a = circuit.add_stretch("a")
    b = circuit.add_stretch("b")
    circuit.delay(expr.add(a, b), 0)
  • Hindi maaaring mag-resolve ang mga stretch expression sa mga negatibong delay value. Ang kasalukuyang solver ay hindi nagpapataw ng mga hadlang sa hindi-negatibidad.

    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))