Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #302 #309

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions bqskit/ir/lang/qasm2/qasm2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from typing import TYPE_CHECKING

from bqskit.ir.gates.measure import MeasurementPlaceholder
from bqskit.ir.lang.language import LangException
from bqskit.ir.lang.language import Language
from bqskit.ir.lang.qasm2.parser import parse
Expand All @@ -22,7 +23,20 @@ def encode(self, circuit: Circuit) -> str:

source = "OPENQASM 2.0;\ninclude \"qelib1.inc\";\n"
source += f'qreg q[{circuit.num_qudits}];\n'
is_classical_register_present = False
for gate in circuit.gate_set:
# add at maximum one classical register definition per gate
if isinstance(gate, MeasurementPlaceholder):
if is_classical_register_present:
# skip all subsequent classical register definitions
continue

if isinstance(gate, MeasurementPlaceholder):
is_classical_register_present = True

print(gate)
print('Gate definition:')
print(gate.get_qasm_gate_def())
source += gate.get_qasm_gate_def()

for op in circuit:
Expand Down
100 changes: 100 additions & 0 deletions tests/ir/lang/test_qasm_encode.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
from __future__ import annotations

from qiskit import ClassicalRegister
from qiskit import QuantumCircuit
from qiskit import QuantumRegister

from bqskit.ext import qiskit_to_bqskit
from bqskit.ir.circuit import Circuit
from bqskit.ir.gates import CNOTGate
from bqskit.ir.gates import Reset
Expand Down Expand Up @@ -55,3 +60,98 @@ def test_reset(self) -> None:
'reset q[0];\n'
)
assert qasm == expected

def test_classical_register(self) -> None:

# Section: Circuit
qr = QuantumRegister(2, name='qr')
cr = ClassicalRegister(2, name='cr')
qc = QuantumCircuit(qr, cr, name='qc')

qc.h(qr[0])
qc.cx(0, 1)

qc.measure(qr, cr)

bqc = qiskit_to_bqskit(qc)
print(bqc)

qasm = OPENQASM2Language().encode(bqc)
expected = (
'OPENQASM 2.0;\n'
'include "qelib1.inc";\n'
'qreg q[2];\n'
'creg cr[2];\n'
'h q[0];\n'
'cx q[0], q[1];\n'
'measure q[0] -> cr[0];\n'
'measure q[1] -> cr[1];\n'
)
assert qasm == expected

def test_multiple_classical_registers(self) -> None:
# Section: Circuit
qr = QuantumRegister(2, name='qr')
cr1 = ClassicalRegister(2, name='cr1')
cr2 = ClassicalRegister(2, name='cr2')
qc = QuantumCircuit(qr, cr1, cr2, name='qc')

qc.h(qr[0])
qc.h(qr[1])
qc.cx(qr[0], qr[1])

qc.measure(qr, cr1)
qc.measure(qr, cr2)

bqc = qiskit_to_bqskit(qc)
print(bqc)

qasm = OPENQASM2Language().encode(bqc)
expected = (
'OPENQASM 2.0;\n'
'include "qelib1.inc";\n'
'qreg q[2];\n'
'creg cr1[2];\n'
'creg cr2[2];\n'
'h q[0];\n'
'h q[1];\n'
'cx q[0], q[1];\n'
'measure q[0] -> cr1[0];\n'
'measure q[1] -> cr1[1];\n'
'measure q[0] -> cr2[0];\n'
'measure q[1] -> cr2[1];\n'
)
assert qasm == expected

def test_gate_count(self) -> None:
# Section: Circuit
qr = QuantumRegister(2, name='qr')
cr = ClassicalRegister(2, name='cr')
qc = QuantumCircuit(qr, cr, name='qc')

qc.h(qr[0])
qc.h(qr[1])
qc.cx(qr[0], qr[1])
qc.measure(qr, cr)

bqc = qiskit_to_bqskit(qc)
print(bqc)

qasm = OPENQASM2Language().encode(bqc)
expected = (
'OPENQASM 2.0;\n'
'include "qelib1.inc";\n'
'qreg q[2];\n'
'creg cr[2];\n'
'h q[0];\n'
'h q[1];\n'
'cx q[0], q[1];\n'
'measure q[0] -> cr[0];\n'
'measure q[1] -> cr[1];\n'
)
assert qasm == expected

print({
gate: bqc.count(gate)
for gate in bqc.gate_set
})
Loading