Skip to content

Commit

Permalink
Remove use of deprecated objects in BasicSimulator (#13743)
Browse files Browse the repository at this point in the history
* Refactor BasicSimulator not to rely on assemble or qobj. Drop support for c_if (deprecated) and providing parameter bounds to the "run" method.

* Code cleanup and style fixing

* Add reno

* Address small oversights

* Apply suggestions from Eli's code review

Co-authored-by: Eli Arbel <[email protected]>

* Fix handling of backend options in both BasicSimulator and BackendV2. Add unit tests. Rename kwargs to unify use of options with aer simulator and update documentation to reflect actual usage.

* Document header in docstring

* Fix lint

* Apply suggestions from Eli's code review

Co-authored-by: Eli Arbel <[email protected]>

---------

Co-authored-by: Eli Arbel <[email protected]>
  • Loading branch information
ElePT and eliarbel authored Feb 4, 2025
1 parent 20b00ce commit 4347eb8
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 519 deletions.
4 changes: 2 additions & 2 deletions qiskit/providers/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,9 @@ def __init__(
self._provider = provider
if fields:
for field in fields:
if field not in self._options.data:
if field not in self._options:
raise AttributeError(f"Options field {field} is not valid for this backend")
self._options.update_config(**fields)
self._options.update_options(**fields)
self.name = name
"""Name of the backend."""
self.description = description
Expand Down
429 changes: 151 additions & 278 deletions qiskit/providers/basic_provider/basic_simulator.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
upgrade_providers:
- |
The ``configuration`` method of :class:`.BasicSimulator` has been removed following its deprecation
in Qiskit 1.3. This method returned a ``BackendConfiguration`` instance, and this class was
part of the deprecated :class:`.BackendV1` workflow. The individual configuration elements
can be retrieved directly from the backend or from the contained :class:`.Target` instance ``(backend.target)``.
- |
The ``run_experiment`` method of :class:`.BasicSimulator` has also been removed. This method took an instance
of the ``QasmQobjExperiment`` class as an input argument, and the class has been deprecated since Qiskit 1.2.
59 changes: 4 additions & 55 deletions test/python/circuit/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1084,46 +1084,6 @@ def test_parameter_equality_to_expression(self, ptype):
self.assertEqual(hash(x1), hash(x1_expr))
self.assertEqual(hash(x2), hash(x2_expr))

def test_binding_parameterized_circuits_built_in_multiproc_(self):
"""Verify subcircuits built in a subprocess can still be bound.
REMOVE this test once assemble is REMOVED"""
# ref: https://github.com/Qiskit/qiskit-terra/issues/2429

num_processes = 4

qr = QuantumRegister(3)
cr = ClassicalRegister(3)

circuit = QuantumCircuit(qr, cr)
parameters = [Parameter(f"x{i}") for i in range(num_processes)]

results = parallel_map(
_construct_circuit, parameters, task_args=(qr,), num_processes=num_processes
)

for qc in results:
circuit.compose(qc, inplace=True)

parameter_values = [{x: 1.0 for x in parameters}]

with self.assertWarns(DeprecationWarning):
qobj = assemble(
circuit,
backend=BasicSimulator(),
parameter_binds=parameter_values,
)

self.assertEqual(len(qobj.experiments), 1)
self.assertEqual(len(qobj.experiments[0].instructions), 4)
self.assertTrue(
all(
len(inst.params) == 1
and isinstance(inst.params[0], float)
and float(inst.params[0]) == 1
for inst in qobj.experiments[0].instructions
)
)

def test_binding_parameterized_circuits_built_in_multiproc(self):
"""Verify subcircuits built in a subprocess can still be bound."""
# ref: https://github.com/Qiskit/qiskit-terra/issues/2429
Expand Down Expand Up @@ -1170,10 +1130,13 @@ def test_transpiling_multiple_parameterized_circuits(self):
qc1.u(theta, 0, 0, qr[0])
qc2.u(theta, 3.14, 0, qr[0])

qc1 = qc1.assign_parameters({theta: 1})
qc2 = qc2.assign_parameters({theta: 1})

circuits = [qc1, qc2]

backend = BasicSimulator()
job = backend.run(transpile(circuits, backend), shots=512, parameter_binds=[{theta: 1}])
job = backend.run(transpile(circuits, backend), shots=512)

self.assertTrue(len(job.result().results), 2)

Expand Down Expand Up @@ -1435,20 +1398,6 @@ def test_num_parameters(self):
qc.x(0)
self.assertEqual(qc.num_parameters, 0)

def test_execute_result_names(self):
"""Test unique names for list of parameter binds."""
theta = Parameter("θ")
reps = 5
qc = QuantumCircuit(1, 1)
qc.rx(theta, 0)
qc.measure(0, 0)

plist = [{theta: i} for i in range(reps)]
simulator = BasicSimulator()
result = simulator.run(transpile(qc, simulator), parameter_binds=plist).result()
result_names = {res.name for res in result.results}
self.assertEqual(reps, len(result_names))

def test_to_instruction_after_inverse(self):
"""Verify converting an inverse generates a valid ParameterTable"""
# ref: https://github.com/Qiskit/qiskit-terra/issues/4235
Expand Down
25 changes: 0 additions & 25 deletions test/python/circuit/test_scheduled_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,32 +518,7 @@ def test_duration_on_same_instruction_instance(self, scheduling_method):
cxs = [inst.operation for inst in sc.data if inst.operation.name == "cx"]
self.assertNotEqual(cxs[0].duration, cxs[1].duration)

def test_transpile_and_assemble_delay_circuit_for_simulator(self):
"""See: https://github.com/Qiskit/qiskit-terra/issues/5962"""
qc = QuantumCircuit(1)
qc.delay(100, 0, "ns")
circ = transpile(qc, self.simulator_backend)
self.assertEqual(circ.duration, None) # not scheduled
with self.assertWarns(DeprecationWarning):
qobj = assemble(circ, self.simulator_backend)
self.assertEqual(qobj.experiments[0].instructions[0].name, "delay")
self.assertEqual(qobj.experiments[0].instructions[0].params[0], 1e-7)

def test_transpile_and_assemble_t1_circuit_for_simulator(self):
"""Check if no scheduling is done in transpiling for simulator backends"""
qc = QuantumCircuit(1, 1)
qc.x(0)
qc.delay(0.1, 0, "us")
qc.measure(0, 0)
circ = transpile(qc, self.simulator_backend)
self.assertEqual(circ.duration, None) # not scheduled
with self.assertWarns(DeprecationWarning):
qobj = assemble(circ, self.simulator_backend)
self.assertEqual(qobj.experiments[0].instructions[1].name, "delay")
self.assertAlmostEqual(qobj.experiments[0].instructions[1].params[0], 1e-7)

# Tests for circuits with parameterized delays

def test_can_transpile_circuits_after_assigning_parameters(self):
"""Check if not scheduled but duration is converted in dt"""
idle_dur = Parameter("t")
Expand Down
7 changes: 0 additions & 7 deletions test/python/providers/basic_provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@
class BasicProviderBackendTestMixin:
"""Test mixins for BasicProvider backend tests."""

def test_configuration(self):
"""Test backend.configuration()."""
with self.assertWarns(DeprecationWarning):
# The method is deprecated
configuration = self.backend.configuration()
return configuration

def test_run_circuit(self):
"""Test running a single circuit."""
transpiled_qc = transpile(self.circuit, self.backend)
Expand Down
Loading

0 comments on commit 4347eb8

Please sign in to comment.