Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Fix bug in submitting qasm3 and add tests. #645

Merged
merged 3 commits into from
May 30, 2023
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
14 changes: 8 additions & 6 deletions qiskit_ibm_provider/ibm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def target_history(self, datetime: Optional[python_datetime] = None) -> Target:
def run(
self,
circuits: Union[
QuantumCircuit, Schedule, List[Union[QuantumCircuit, Schedule]]
QuantumCircuit, Schedule, str, List[Union[QuantumCircuit, Schedule, str]]
],
dynamic: bool = None,
job_tags: Optional[List[str]] = None,
Expand Down Expand Up @@ -823,11 +823,13 @@ def _check_circuits_attributes(self, circuits: List[QuantumCircuit]) -> None:
for circ in circuits:
if isinstance(circ, Schedule):
raise IBMBackendValueError(schedule_error_msg)
if circ.num_qubits > self._configuration.num_qubits:
raise IBMBackendValueError(
f"Circuit contains {circ.num_qubits} qubits, but backend has only {self.num_qubits}."
)
self._check_faulty(circ)
if isinstance(circ, QuantumCircuit):
if circ.num_qubits > self._configuration.num_qubits:
raise IBMBackendValueError(
f"Circuit contains {circ.num_qubits} qubits, "
f"but backend has only {self.num_qubits}."
)
self._check_faulty(circ)

def _check_faulty(self, circuit: QuantumCircuit) -> None:
"""Check if the input circuit uses faulty qubits or edges.
Expand Down
2 changes: 2 additions & 0 deletions qiskit_ibm_provider/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ def _filter_value(
def are_circuits_dynamic(circuits: List[QuantumCircuit]) -> bool:
"""Checks if the input circuits are dynamic."""
for circuit in circuits:
if isinstance(circuit, str):
return True
for inst in circuit:
if (
isinstance(inst.operation, ControlFlowOp)
Expand Down
96 changes: 95 additions & 1 deletion test/unit/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from unittest import mock
import warnings

from qiskit import transpile, QuantumCircuit
from qiskit import transpile, qasm3, QuantumCircuit
from qiskit.providers.fake_provider import FakeManila
from qiskit.providers.models import BackendStatus, BackendProperties

Expand Down Expand Up @@ -224,3 +224,97 @@ def test_dynamic_circuits_warning(self):
f"The backend {backend.name} does not support dynamic circuits.",
str(warn[1].message),
)

def _create_dc_test_backend(self):
"""Create a test backend with an IfElseOp enables."""
model_backend = FakeManila()
properties = model_backend.properties()

out_backend = IBMBackend(
configuration=model_backend.configuration(),
provider=mock.MagicMock(),
api_client=None,
instance=None,
)

out_backend.status = lambda: BackendStatus(
backend_name="foo",
backend_version="1.0",
operational=True,
pending_jobs=0,
status_msg="",
)
out_backend.properties = lambda: properties

return out_backend

def test_single_dynamic_circuit_submission(self):
"""Test submitting single circuit with dynamic=True"""
# pylint: disable=not-context-manager

backend = self._create_dc_test_backend()

circ = QuantumCircuit(2, 2)
circ.measure(0, 0)
with circ.if_test((0, False)):
circ.x(1)

with mock.patch.object(IBMBackend, "_runtime_run") as mock_run:
backend.run(circuits=circ, dynamic=True)

mock_run.assert_called_once()

def test_multi_dynamic_circuit_submission(self):
"""Test submitting multiple circuits with dynamic=True"""
# pylint: disable=not-context-manager

backend = self._create_dc_test_backend()

circ = QuantumCircuit(2, 2)
circ.measure(0, 0)
with circ.if_test((0, False)):
circ.x(1)

circuits = [circ, circ]

with mock.patch.object(IBMBackend, "_runtime_run") as mock_run:
backend.run(circuits=circuits, dynamic=True)

mock_run.assert_called_once()

def test_single_openqasm3_submission(self):
"""Test submitting a single openqasm3 strings with dynamic=True"""
# pylint: disable=not-context-manager

backend = self._create_dc_test_backend()

circ = QuantumCircuit(2, 2)
circ.measure(0, 0)
with circ.if_test((0, False)):
circ.x(1)

qasm3_circ = qasm3.dumps(circ, disable_constants=True)

with mock.patch.object(IBMBackend, "_runtime_run") as mock_run:
backend.run(circuits=qasm3_circ, dynamic=True)

mock_run.assert_called_once()

def test_multi_openqasm3_submission(self):
"""Test submitting multiple openqasm3 strings with dynamic=True"""
# pylint: disable=not-context-manager

backend = self._create_dc_test_backend()

circ = QuantumCircuit(2, 2)
circ.measure(0, 0)
with circ.if_test((0, False)):
circ.x(1)

qasm3_circ = qasm3.dumps(circ, disable_constants=True)
qasm3_circs = [qasm3_circ, qasm3_circ]

with mock.patch.object(IBMBackend, "_runtime_run") as mock_run:
backend.run(circuits=qasm3_circs, dynamic=True)

mock_run.assert_called_once()