cQASMv1 exporter
The cQASM v1 exporter (ExportFormat.CQASM_V1
) exports the circuit to a string that adheres to the
cQASM version 1.0 language specification.
Here are some important differences to take note of:
- The version statement
changes from
version 3.<m>
(where<m>
refers to the minor version number) toversion 1.0
. - All qubit register declarations
are combined into a single (virtual) qubit register (
q
) statement. - Bit registers declarations
and assignments of measurement outcomes to bit register variables
are discarded; cQASM version 1.0 does not support bit registers or variables.
Note that the measurement statement is not discarded; the
measure
instruction is translated tomeasure_z
. The outcome of a measurement on qubit at (virtual) index i will be stored at index i in the measurement register. - The non-unitary
init
andreset
instructions are both translated toprep_z
. - Instructions are translated to lowercase; even though, cQASM version 1.0 is not case-sensitive.
- Single gate multi qubit (SGMQ) notation is unpacked; the gate is applied to each qubit on a separate line.
- Consecutive
barrier
instructions are grouped in SGMQ notation to form a uniform barrier, across which no instructions on the specified qubits can be scheduled.
Unsupported gates
cQASM version 1.0 does not support the Rn gate
and will raise an error (UnSupportedGateError
) if this gate is part of the circuit that is to be exported.
A single-qubit decomposition pass can be used to decompose the circuit to gates that
the cQASM v1 exporter supports.
The four examples below show how circuits written in cQASM are exported to cQASM v1.
circuit = Circuit.from_string(
"""
version 3.0
qubit[2] q
bit[2] b
H q[0]
CNOT q[0], q[1]
b = measure q
"""
)
exported_circuit = circuit.export(fmt=ExportFormat.CQASM_V1)
print(exported_circuit)
Note that the version statement is changed (1.), the qubit register declaration is made into a statement (2.), the bit register declaration and assignment to bit variables have been discarded (3.), the instructions are in lowercase (5.), and the SGMQ notation has been unpacked (6.). The numbers refer to the differences listed above.
circuit = Circuit.from_string(
"""
version 3.0
qubit[2] qA
bit[3] bA
H qA[0]
CNOT qA[0], qA[1]
bA[1,2] = measure qA
qubit[3] qB
bit[2] bB
H qB[1]
CNOT qB[1], qA[1]
bB[0] = measure qB[1]
bB[1] = measure qA[1]
"""
)
exported_circuit = circuit.export(fmt=ExportFormat.CQASM_V1)
print(exported_circuit)
version 1.0
qubits 5
h q[0]
cnot q[0], q[1]
measure_z q[0]
measure_z q[1]
h q[3]
cnot q[3], q[1]
measure_z q[3]
measure_z q[1]
Note that the version statement is changed (1.), the qubit register declaration is made into a statement (2.), the bit register declaration and assignment to bit variables have been discarded (3.), the instructions are in lowercase (5.), and the SGMQ notation has been unpacked (6.). The numbers refer to the differences listed above.
In particular, this example illustrates that all qubit registers have been combined into a single (virtual)
qubit register q
, i.e., the registers qA
and qB
have been concatenated into q
,
such that qA[0], qA[1] = q[0], q[1]
and qB[0], qB[1], qB[2] = q[2], q[3], q[4]
.
The qubit registers are concatenated in the order they are declared.
Moreover, the bit registers have been discarded and the measurement instructions measure_z
implicitly assign
the measurement outcomes to the bit/measurement register index corresponding to the index of the (virtual) qubit
that is measured. For instance, bB[0] = measure qB[1]
is translated to measure_z q[3]
,
and the outcome will bestored at index 3 in the bit/measurement register.
This also implies that different measurements on the same qubit, at (virtual) index i will always be stored in
the same place, i.e. at index i, on the bit/measurement register.
Which further implies that outcomes of subsequent measurements on the same qubit always overwrite the outcome of
the previous measurement.
circuit = Circuit.from_string(
"""
version 3.0
qubit[2] q
bit[2] b
init q
H q[0]
CNOT q[0], q[1]
b = measure q
reset q
H q[0]
Z q[0]
CNOT q[0], q[1]
b = measure q
"""
)
exported_circuit = circuit.export(fmt=ExportFormat.CQASM_V1)
print(exported_circuit)
version 1.0
qubits 2
prep_z q[0]
prep_z q[1]
h q[0]
cnot q[0], q[1]
measure_z q[0]
measure_z q[1]
prep_z q[0]
prep_z q[1]
h q[0]
z q[0]
cnot q[0], q[1]
measure_z q[0]
measure_z q[1]
Note that the version statement is changed (1.), the qubit register declaration is made into a statement (2.),
the bit register declaration and assignment to bit variables have been discarded (3.),
the init
and reset
instructions are both translated to prep_z
(4.),
the instructions are in lowercase (5.), and the SGMQ notation has been unpacked (6.).
The numbers refer to the differences listed above.
In cQASM version 1.0, one cannot distinguish between an init
and a reset
instruction.
The definition of the prep_z
instruction is close to that of the reset
instruction, i.e.,
the state of the qubit is set to \(|0\rangle\) by first measuring it and then,
conditioned on the outcome being 1, applying a Pauli-X gate.
circuit = Circuit.from_string(
"""
version 3.0
qubit[4] q
bit[4] b
init q[0,1]
barrier q[0]
H q[0]
CNOT q[0], q[1]
init q[2]
barrier q[0]
barrier q[1]
barrier q[2]
H q[2]
b[0,1] = measure q[0,1]
init q[3]
barrier q[2, 3]
Z q[2]
CNOT q[2], q[3]
b[2,3] = measure q[2,3]
"""
)
exported_circuit = circuit.export(fmt=ExportFormat.CQASM_V1)
print(exported_circuit)
version 1.0
qubits 4
prep_z q[0]
prep_z q[1]
barrier q[0]
h q[0]
cnot q[0], q[1]
prep_z q[2]
barrier q[0, 1, 2]
h q[2]
measure_z q[0]
measure_z q[1]
prep_z q[3]
barrier q[2, 3]
z q[2]
cnot q[2], q[3]
measure_z q[2]
measure_z q[3]
Note that the version statement is changed (1.), the qubit register declaration is made into a statement (2.),
the bit register declaration and assignment to bit variables have been discarded (3.),
the init
instruction is translated to prep_z
(4.),
the instructions are in lowercase (5.), the SGMQ notation has been unpacked (6.) and consecutive barrier
have been grouped in SGMQ notation to form a uniform barrier (7.).
The numbers refer to the differences listed above.
The three consecutive barrier instructions, following the init q[2]
statement, have been grouped using SGMQ
notation.
They form a uniform barrier across all the specified qubits, instead of a single barrier on each of the
respective qubits.
Also, in contrast to other instructions where the SGMQ notation has been unpacked, the SGMQ notation for the
statement barrier q[2, 3]
has been preserved.