OpenQASM3 Transport Roundtrip¶
This tutorial shows how to serialize a QPP HamiltonianGate circuit to an OpenQASM3-compatible transport format and load it back into an executable QPP circuit.
The transport helpers are:
dumps_qpp_openqasm3loads_qpp_openqasm3
Imports¶
We import the QPP gate classes, OpenQASM3 transport helpers, and a local sampler backend.
[1]:
"""OpenQASM3 transport roundtrip tutorial."""
from qiskit.circuit import QuantumCircuit
from qiskit_pasqal_provider.providers.gate import (
HamiltonianGate,
InterpolatePoints,
dumps_qpp_openqasm3,
loads_qpp_openqasm3,
)
from qiskit_pasqal_provider.providers.provider import PasqalProvider
from qiskit_pasqal_provider.providers.sampler import SamplerV2
Build The Original Program¶
Create a circuit with one Pasqal analog HamiltonianGate.
[2]:
coords = [[0, 0], [3, 5.2], [6, 0], [9, -5.2], [9, 5.2], [12, 0]]
times = [0, 0.2, 0.8, 1]
ampl = InterpolatePoints(values=[0, 4, 4, 0], times=times)
det = InterpolatePoints(values=[-10, -10, -5, -5], times=times)
qc = QuantumCircuit(len(coords))
qc.append(HamiltonianGate(ampl, det, 0.0, coords), qc.qubits)
print(qc)
┌─────┐
q_0: ┤0 ├
│ │
q_1: ┤1 ├
│ │
q_2: ┤2 ├
│ Hg │
q_3: ┤3 ├
│ │
q_4: ┤4 ├
│ │
q_5: ┤5 ├
└─────┘
Run Original Program¶
Run the original circuit first so we have a baseline before conversion.
[3]:
sampler = SamplerV2(PasqalProvider().get_backend("qutip"))
original_result = sampler.run([qc], shots=100).result()
print(original_result[0].data.counts)
Counter({'000000': 31, '001000': 17, '000010': 12, '000001': 9, '100000': 9, '000100': 7, '010000': 7, '010001': 4, '100100': 1, '100010': 1, '001010': 1, '010100': 1})
Serialize The Sequence To OpenQASM3 Transport Format¶
Serialize the circuit to OpenQASM3 transport format and inspect the content.
[4]:
QASM_PROGRAM = dumps_qpp_openqasm3(qc)
print("\n".join(QASM_PROGRAM.splitlines()[:8]))
OPENQASM 3.0;
include "stdgates.inc";
gate HG(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39) q0, q1, q2, q3, q4, q5 {}
qubit[6] q;
HG(1.0, 6.0, 1.0, 0, 0, 1000.0, 4.0, 4.0, 0, 4.0, 4.0, 0, -6.5, -0.8666666666666667, -3.5, 4.333333333333334, -0.5, -0.8666666666666667, 2.5, -6.066666666666666, 2.5, 4.333333333333334, 5.5, -0.8666666666666667, 0, 4.0, 4.0, 0, 0, 0.2, 0.8, 1.0, -10.0, -10.0, -5.0, -5.0, 0, 0.2, 0.8, 1.0) q[0], q[1], q[2], q[3], q[4], q[5];
Run Restored Program¶
Run the restored circuit. Both circuits should execute, and should have the same probability distribution.
[5]:
restored = loads_qpp_openqasm3(QASM_PROGRAM)
print("original:", qc.num_qubits, qc.count_ops())
print("restored:", restored.num_qubits, restored.count_ops())
restored_result = sampler.run([restored], shots=100).result()
print(restored_result[0].data.counts)
original: 6 OrderedDict({'HG': 1})
restored: 6 OrderedDict({'HG': 1})
Counter({'000000': 33, '001000': 16, '000001': 9, '000010': 9, '100000': 8, '000100': 7, '010000': 7, '100001': 3, '010001': 3, '100010': 2, '010100': 1, '000110': 1, '100110': 1})