Skip to content

Commit 0bb117f

Browse files
daxfohlrht
authored andcommitted
Deprecate implementation of _base_iterator (quantumlib#5402)
Fixes quantumlib#5400 Add a deprecation warning that _base_iterator is going to be made abstract, and copy (with intent to move) the implementation to SimulatorBase. Once the deprecation timeline has passed we can safely make `SimulatesIntermediateState._base_iterator` abstract, and remove `_create_simulation_state`, `_create_act_on_args` and `_core_iterator` declarations from `SimulatesIntermediateState` completely. This makes `SimulatesIntermediateState` more true to its name, as it should not be concerned with how or where the subclass creates the initial state, even from the interface standpoint. @95-martin-orion
1 parent bab9e73 commit 0bb117f

File tree

4 files changed

+66
-15
lines changed

4 files changed

+66
-15
lines changed

cirq-core/cirq/sim/simulator.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -655,25 +655,17 @@ def simulate_moment_steps(
655655
resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
656656
check_all_resolved(resolved_circuit)
657657
actual_initial_state = 0 if initial_state is None else initial_state
658-
return self._base_iterator(resolved_circuit, qubit_order, actual_initial_state)
658+
qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(circuit.all_qubits())
659+
return self._base_iterator(resolved_circuit, qubits, actual_initial_state)
659660

660661
def _base_iterator(
661-
self,
662-
circuit: 'cirq.AbstractCircuit',
663-
qubit_order: 'cirq.QubitOrderOrList',
664-
initial_state: Any,
662+
self, circuit: 'cirq.AbstractCircuit', qubits: Tuple['cirq.Qid', ...], initial_state: Any
665663
) -> Iterator[TStepResult]:
666664
"""Iterator over StepResult from Moments of a Circuit.
667665
668-
This is a thin wrapper around `create_act_on_args` and `_core_iterator`.
669-
Overriding this method was the old way of creating a circuit iterator,
670-
and this method is planned to be formally put on the deprecation path.
671-
Going forward, override the aforementioned two methods in custom
672-
simulators.
673-
674666
Args:
675667
circuit: The circuit to simulate.
676-
qubit_order: Determines the canonical ordering of the qubits. This
668+
qubits: Specifies the canonical ordering of the qubits. This
677669
is often used in specifying the initial state, i.e. the
678670
ordering of the computational basis states.
679671
initial_state: The initial state for the simulation. The form of
@@ -683,7 +675,22 @@ def _base_iterator(
683675
Yields:
684676
StepResults from simulating a Moment of the Circuit.
685677
"""
686-
qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(circuit.all_qubits())
678+
# In 0.16 (or 1.0) _base_iterator should be made abstract. Then _create_simulation_state,
679+
# _create_act_on_args, and _core_iterator can all be removed from this class completely.
680+
# (They were only required because of this implementation, which has been moved to
681+
# SimulatorBase instead).
682+
_compat._warn_or_error(
683+
'Custom implementations of `cirq.SimulatesIntermediateState` should implement'
684+
' `_base_iterator` directly rather than implementing both `_create_simulation_state`'
685+
' and `_core_iterator`. The default implementation of `_base_iterator` will be removed'
686+
' in v0.16, and the method will become abstract.'
687+
)
688+
if not isinstance(qubits, tuple):
689+
_compat._warn_or_error(
690+
'The `qubits` parameter of `_base_iterator` will expect an explicit'
691+
' `Tuple[cirq.Qid, ...]` beginning in v0.16.'
692+
)
693+
qubits = ops.QubitOrder.as_qubit_order(qubits).order_for(circuit.all_qubits())
687694
sim_state = self._create_simulation_state(initial_state, qubits)
688695
return self._core_iterator(circuit, sim_state)
689696

@@ -736,7 +743,6 @@ def _create_simulation_state(
736743
# remove this implementation, and delete `_create_act_on_args` entirely.
737744
return self._create_act_on_args(initial_state, qubits)
738745

739-
@abc.abstractmethod
740746
def _core_iterator(
741747
self,
742748
circuit: 'cirq.AbstractCircuit',
@@ -758,6 +764,7 @@ def _core_iterator(
758764
Yields:
759765
StepResults from simulating a Moment of the Circuit.
760766
"""
767+
raise NotImplementedError()
761768

762769
@abc.abstractmethod
763770
def _create_simulator_trial_result(

cirq-core/cirq/sim/simulator_base.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,18 @@ def _can_be_in_run_prefix(self, val: Any):
210210
`_run` prefix."""
211211
return protocols.has_unitary(val)
212212

213+
def _base_iterator(
214+
self, circuit: 'cirq.AbstractCircuit', qubits: Tuple['cirq.Qid', ...], initial_state: Any
215+
) -> Iterator[TStepResultBase]:
216+
if not isinstance(qubits, tuple):
217+
_compat._warn_or_error(
218+
'The `qubits` parameter of `_base_iterator` will expect an explicit'
219+
' `Tuple[cirq.Qid, ...]` beginning in v0.16.'
220+
)
221+
qubits = ops.QubitOrder.as_qubit_order(qubits).order_for(circuit.all_qubits())
222+
sim_state = self._create_simulation_state(initial_state, qubits)
223+
return self._core_iterator(circuit, sim_state)
224+
213225
def _core_iterator(
214226
self,
215227
circuit: 'cirq.AbstractCircuit',

cirq-core/cirq/sim/simulator_base_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,21 @@ def _create_simulator_trial_result(self):
443443
sim.simulate_moment_steps(cirq.Circuit())
444444

445445

446+
def test_deprecated_qubits_param():
447+
class Sim(cirq.SimulatorBase):
448+
def _create_partial_simulation_state(self, initial_state, qubits, classical_data):
449+
return 0
450+
451+
def _create_step_result(self):
452+
pass
453+
454+
def _create_simulator_trial_result(self):
455+
pass
456+
457+
with cirq.testing.assert_deprecated('`qubits` parameter of `_base_iterator', deadline='v0.16'):
458+
Sim()._base_iterator(cirq.Circuit(), cirq.QubitOrder.explicit([]), 0)
459+
460+
446461
def test_deprecated_setters():
447462
sim = CountingSimulator()
448463
with cirq.testing.assert_deprecated(deadline='v0.16'):

cirq-core/cirq/sim/simulator_test.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,10 +553,27 @@ def _create_simulator_trial_result(self):
553553
pass
554554

555555
sim = DeprecatedSim()
556-
with cirq.testing.assert_deprecated(deadline='v0.16'):
556+
with cirq.testing.assert_deprecated(deadline='v0.16', count=2):
557557
sim.simulate_moment_steps(cirq.Circuit())
558558

559559

560+
def test_deprecated_qubits_param():
561+
class Sim(cirq.SimulatesIntermediateState):
562+
def _create_simulation_state(self, initial_state, qubits):
563+
return 0
564+
565+
def _core_iterator(self, circuit, sim_state):
566+
pass
567+
568+
def _create_simulator_trial_result(self):
569+
pass
570+
571+
with cirq.testing.assert_deprecated(
572+
'`qubits` parameter of `_base_iterator', deadline='v0.16', count=2
573+
):
574+
Sim()._base_iterator(cirq.Circuit(), cirq.QubitOrder.explicit([]), 0)
575+
576+
560577
def test_deprecated_setters():
561578
step = FakeStepResult()
562579
result = cirq.SimulationTrialResult(cirq.ParamResolver(), {}, 0)

0 commit comments

Comments
 (0)