From 2988803bb3c0def51797151a35be37bdcfff516d Mon Sep 17 00:00:00 2001 From: Dax Fohl Date: Thu, 26 Aug 2021 15:58:02 -0700 Subject: [PATCH] Retain log_of_measurement_results throughout simulation (#4465) Breaking change: Step results will include all measurements from previous moments in the simulation. Part of https://tinyurl.com/cirq-feedforward, PR 4 Rationale: with feedforward and flow control, classical state is just as much part of the simulation as quantum state. The ActOnArgs *must* contain the full classical state to check whether gates should be applied. For step results, each step result contains the aggregate quantum state, and should also contain the aggregate classical state, hence the breaking change. This also simplifies analyzing results, as you can look only at the final step result to get all measurements rather than having to traverse them all. --- cirq-core/cirq/sim/simulator_base.py | 10 +++++----- cirq-core/cirq/sim/simulator_base_test.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cirq-core/cirq/sim/simulator_base.py b/cirq-core/cirq/sim/simulator_base.py index e56c440eced..20b752446b8 100644 --- a/cirq-core/cirq/sim/simulator_base.py +++ b/cirq-core/cirq/sim/simulator_base.py @@ -225,7 +225,6 @@ def _core_iterator( step_result = self._create_step_result(sim_state) yield step_result sim_state = step_result._sim_state - sim_state.log_of_measurement_results.clear() # pylint: enable=missing-param-doc,missing-raises-doc def _run( @@ -275,10 +274,11 @@ def _run( sim_state=act_on_args.copy() if i < repetitions - 1 else act_on_args, ) for step_result in all_step_results: - for k, v in step_result.measurements.items(): - if k not in measurements: - measurements[k] = [] - measurements[k].append(np.array(v, dtype=np.uint8)) + pass + for k, v in step_result.measurements.items(): + if k not in measurements: + measurements[k] = [] + measurements[k].append(np.array(v, dtype=np.uint8)) return {k: np.array(v) for k, v in measurements.items()} def _create_act_on_args( diff --git a/cirq-core/cirq/sim/simulator_base_test.py b/cirq-core/cirq/sim/simulator_base_test.py index f3fe26a1b32..b8f9e8b55bb 100644 --- a/cirq-core/cirq/sim/simulator_base_test.py +++ b/cirq-core/cirq/sim/simulator_base_test.py @@ -374,3 +374,15 @@ def test_sim_state_instance_gets_changes_from_step_result(split: bool): args = sim._create_act_on_args(0, (q0, q1)) step._sim_state = args assert (step._merged_sim_state is not args) == split + + +def test_measurements_retained_in_step_results(): + sim = SplittableCountingSimulator() + circuit = cirq.Circuit( + cirq.measure(q0, key='a'), cirq.measure(q0, key='b'), cirq.measure(q0, key='c') + ) + iterator = sim.simulate_moment_steps(circuit) + assert next(iterator).measurements.keys() == {'a'} + assert next(iterator).measurements.keys() == {'a', 'b'} + assert next(iterator).measurements.keys() == {'a', 'b', 'c'} + assert not any(iterator)