Skip to content

✨ Added QASM3 support #518

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

Merged
Merged
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
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ dependencies = [
"pytket-qiskit>=0.53.0",
# lowest version that supports the used pytket AutoRebase pass instead of auto_rebase
"pytket>=1.29.0",
# there is a bug in 1.2.0 that causes an error some benchmarks, see https://github.com/Qiskit/qiskit/issues/12969
"qiskit!=1.2.0",
# Qiskit 1.2.1 contains some fixes for importing OpenQASM 3 files
"qiskit>=1.2.1",
"qiskit_ibm_runtime<0.37.0", # FakeBackends have been removed with 0.37.0
"qiskit-aer!=0.16.1", # excludig 0.16.1 due to an CI error for linux arm64 runners
"qiskit_qasm3_import>=0.5.0",
"networkx>=2.8.8",
"joblib>=1.3.0",
"numpy>=1.26; python_version >= '3.12'",
Expand Down
146 changes: 84 additions & 62 deletions src/mqt/bench/benchmark_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
file_precheck: bool,
) -> None:
"""Generate all benchmarks for a given benchmark."""
self.generate_alg_levels(file_precheck, lib, parameter_space)

Check warning on line 145 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L145

Added line #L145 was not covered by tests
self.generate_indep_levels(file_precheck, lib, parameter_space)
self.generate_native_gates_levels(file_precheck, lib, parameter_space)
self.generate_mapped_levels(file_precheck, lib, parameter_space)
Expand All @@ -154,104 +155,124 @@
) -> None:
"""Generate mapped level benchmarks for a given benchmark."""
for provider in get_available_providers():
for device in provider.get_available_devices():
for opt_level in [0, 1, 2, 3]:
for qasm_format in ["qasm2", "qasm3"]:
for device in provider.get_available_devices():
for opt_level in [0, 1, 2, 3]:
for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
if qc.num_qubits <= device.num_qubits:
res = timeout_watcher(

Check warning on line 167 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L158-L167

Added lines #L158 - L167 were not covered by tests
qiskit_helper.get_mapped_level,
self.timeout,
[
qc,
qc.num_qubits,
device,
opt_level,
file_precheck,
False,
self.qasm_output_path,
qasm_format,
],
)
if not res:
break

Check warning on line 182 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L181-L182

Added lines #L181 - L182 were not covered by tests
else:
break

Check warning on line 184 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L184

Added line #L184 was not covered by tests

for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
if qc.num_qubits <= device.num_qubits:
res = timeout_watcher(
qiskit_helper.get_mapped_level,
tket_helper.get_mapped_level,
self.timeout,
[
qc,
qc.num_qubits,
device,
opt_level,
file_precheck,
False,
self.qasm_output_path,
],
[qc, qc.num_qubits, device, file_precheck, False, self.qasm_output_path, qasm_format],
)
if not res:
break
else:
break

for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
if qc.num_qubits <= device.num_qubits:
def generate_native_gates_levels(
self,
file_precheck: bool,
lib: ModuleType,
parameter_space: list[tuple[int, str]] | list[int] | list[str] | range,
) -> None:
"""Generate native gates level benchmarks for a given benchmark."""
for provider in get_available_providers():
for qasm_format in ["qasm2", "qasm3"]:
for opt_level in [0, 1, 2, 3]:
for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)

Check warning on line 216 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L209-L216

Added lines #L209 - L216 were not covered by tests
res = timeout_watcher(
tket_helper.get_mapped_level,
qiskit_helper.get_native_gates_level,
self.timeout,
[
qc,
provider,
qc.num_qubits,
device,
opt_level,
file_precheck,
False,
self.qasm_output_path,
qasm_format,
],
)
if not res:
break
else:
break

def generate_native_gates_levels(
self,
file_precheck: bool,
lib: ModuleType,
parameter_space: list[tuple[int, str]] | list[int] | list[str] | range,
) -> None:
"""Generate native gates level benchmarks for a given benchmark."""
for provider in get_available_providers():
for opt_level in [0, 1, 2, 3]:
for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
res = timeout_watcher(
qiskit_helper.get_native_gates_level,
tket_helper.get_native_gates_level,
self.timeout,
[
qc,
provider,
qc.num_qubits,
opt_level,
file_precheck,
False,
self.qasm_output_path,
qasm_format,
],
)
if not res:
break

def generate_alg_levels(
self,
file_precheck: bool,
lib: ModuleType,
parameter_space: list[tuple[int, str]] | list[int] | list[str] | range,
) -> None:
"""Generate algorithm level benchmarks for a given benchmark."""
for function in [qiskit_helper.get_alg_level]:

Check warning on line 262 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L262

Added line #L262 was not covered by tests
for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
res = timeout_watcher(
tket_helper.get_native_gates_level,
self.timeout,
[
qc,
provider,
qc.num_qubits,
file_precheck,
False,
self.qasm_output_path,
],
)
if not res:
break
for qasm_format in ["qasm3"]:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
res = timeout_watcher(

Check warning on line 269 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L264-L269

Added lines #L264 - L269 were not covered by tests
function,
self.timeout,
[qc, qc.num_qubits, file_precheck, False, self.qasm_output_path, qasm_format],
)
if not res:
break

Check warning on line 275 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L274-L275

Added lines #L274 - L275 were not covered by tests

def generate_indep_levels(
self,
Expand All @@ -262,17 +283,18 @@
"""Generate independent level benchmarks for a given benchmark."""
for function in [qiskit_helper.get_indep_level, tket_helper.get_indep_level]:
for parameter_instance in parameter_space:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
res = timeout_watcher(
function,
self.timeout,
[qc, qc.num_qubits, file_precheck, False, self.qasm_output_path],
)
if not res:
break
for qasm_format in ["qasm2", "qasm3"]:
qc = timeout_watcher(lib.create_circuit, self.timeout, parameter_instance)
if not qc:
break
assert isinstance(qc, QuantumCircuit)
res = timeout_watcher(

Check warning on line 291 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L286-L291

Added lines #L286 - L291 were not covered by tests
function,
self.timeout,
[qc, qc.num_qubits, file_precheck, False, self.qasm_output_path, qasm_format],
)
if not res:
break

Check warning on line 297 in src/mqt/bench/benchmark_generator.py

View check run for this annotation

Codecov / codecov/patch

src/mqt/bench/benchmark_generator.py#L296-L297

Added lines #L296 - L297 were not covered by tests


@overload
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/bench/benchmarks/ae.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def create_circuit(num_qubits: int, probability: float = 0.2) -> QuantumCircuit:
qc.compose(state_preparation, list(range(num_eval_qubits, qc.num_qubits)), inplace=True)

# Compose the phase estimation component.
qc.compose(pe, inplace=True)
qc.compose(pe.decompose(gates_to_decompose="unitary"), inplace=True)

# Name the circuit and add measurements to all evaluation qubits.
qc.name = "ae"
Expand Down
3 changes: 1 addition & 2 deletions src/mqt/bench/benchmarks/graphstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ def create_circuit(num_qubits: int, degree: int = 2) -> QuantumCircuit:
a = nx.convert_matrix.to_numpy_array(g)
qc.compose(GraphState(a), inplace=True)
qc.measure_all()

return qc
return qc.decompose(gates_to_decompose="graph_state")
Loading
Loading