def example_bsa() -> 'cw.BitstringAccumulator': """Test fixture to create an (empty) example BitstringAccumulator""" q0, q1 = cirq.LineQubit.range(2) setting = cw.InitObsSetting(init_state=cirq.KET_ZERO(q0) * cirq.KET_ZERO(q1), observable=cirq.X(q0) * cirq.Y(q1)) meas_spec = _MeasurementSpec( max_setting=setting, circuit_params={ 'beta': 0.123, 'gamma': 0.456, }, ) bsa = cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[ setting, cw.InitObsSetting(init_state=setting.init_state, observable=cirq.X(q0)), cw.InitObsSetting(init_state=setting.init_state, observable=cirq.Y(q1)), ], qubit_to_index={ q0: 0, q1: 1 }, ) return bsa
def test_params_and_settings(): qubits = cirq.LineQubit.range(1) (q, ) = qubits tests = [ (cirq.KET_ZERO, cirq.Z, 1), (cirq.KET_ONE, cirq.Z, -1), (cirq.KET_PLUS, cirq.X, 1), (cirq.KET_MINUS, cirq.X, -1), (cirq.KET_IMAG, cirq.Y, 1), (cirq.KET_MINUS_IMAG, cirq.Y, -1), (cirq.KET_ZERO, cirq.Y, 0), ] for init, obs, coef in tests: setting = cw.InitObsSetting(init_state=init(q), observable=obs(q)) circuit = cirq.Circuit(cirq.I.on_each(*qubits)) circuit = _with_parameterized_layers(circuit, qubits=qubits, needs_init_layer=True) params = _get_params_for_setting(setting, flips=[False], qubits=qubits, needs_init_layer=True) circuit = circuit[:-1] # remove measurement so we can compute <Z> psi = cirq.Simulator().simulate(circuit, param_resolver=params) z = cirq.Z(q).expectation_from_state_vector(psi.final_state_vector, qubit_map=psi.qubit_map) assert np.abs(coef - z) < 1e-2, f'{init} {obs} {coef}'
def test_measure_grouped_settings_read_checkpoint(tmpdir): qubits = cirq.LineQubit.range(1) (q,) = qubits setting = cw.InitObsSetting( init_state=cirq.KET_ZERO(q), observable=cirq.Z(q), ) grouped_settings = {setting: [setting]} circuit = cirq.Circuit(cirq.I.on_each(*qubits)) with pytest.raises(ValueError, match=r'same filename.*'): _ = cw.measure_grouped_settings( circuit=circuit, grouped_settings=grouped_settings, sampler=cirq.Simulator(), stopping_criteria=cw.RepetitionsStoppingCriteria(1_000, repetitions_per_chunk=500), checkpoint=True, checkpoint_fn=f'{tmpdir}/obs.json', checkpoint_other_fn=f'{tmpdir}/obs.json', # Same filename ) _ = cw.measure_grouped_settings( circuit=circuit, grouped_settings=grouped_settings, sampler=cirq.Simulator(), stopping_criteria=cw.RepetitionsStoppingCriteria(1_000, repetitions_per_chunk=500), checkpoint=True, checkpoint_fn=f'{tmpdir}/obs.json', checkpoint_other_fn=f'{tmpdir}/obs.prev.json', ) results = cirq.read_json(f'{tmpdir}/obs.json') (result,) = results # one group assert result.n_repetitions == 1_000 assert result.means() == [1.0]
def test_get_params_for_setting(): qubits = cirq.LineQubit.range(3) a, b, c = qubits init_state = cirq.KET_PLUS(a) * cirq.KET_ZERO(b) observable = cirq.X(a) * cirq.Y(b) setting = cw.InitObsSetting(init_state=init_state, observable=observable) padded_setting = _pad_setting(setting, qubits=qubits) assert padded_setting.init_state == cirq.KET_PLUS(a) * cirq.KET_ZERO( b) * cirq.KET_ZERO(c) assert padded_setting.observable == cirq.X(a) * cirq.Y(b) * cirq.Z(c) assert init_state == cirq.KET_PLUS(a) * cirq.KET_ZERO(b) assert observable == cirq.X(a) * cirq.Y(b) needs_init_layer = True with pytest.raises(ValueError): _get_params_for_setting( padded_setting, flips=[0, 0], qubits=qubits, needs_init_layer=needs_init_layer, ) params = _get_params_for_setting( padded_setting, flips=[0, 0, 1], qubits=qubits, needs_init_layer=needs_init_layer, ) assert all(x in params for x in [ '0-Xf', '0-Yf', '1-Xf', '1-Yf', '2-Xf', '2-Yf', '0-Xi', '0-Yi', '1-Xi', '1-Yi', '2-Xi', '2-Yi', ]) circuit = cirq.Circuit(cirq.I.on_each(*qubits)) circuit = _with_parameterized_layers( circuit, qubits=qubits, needs_init_layer=needs_init_layer, ) circuit = circuit[:-1] # remove measurement so we can compute <Z> psi = cirq.Simulator().simulate(circuit, param_resolver=params) ma = cirq.Z(a).expectation_from_state_vector(psi.final_state_vector, qubit_map=psi.qubit_map) mb = cirq.Z(b).expectation_from_state_vector(psi.final_state_vector, qubit_map=psi.qubit_map) mc = cirq.Z(c).expectation_from_state_vector(psi.final_state_vector, qubit_map=psi.qubit_map) np.testing.assert_allclose([ma, mb, mc], [1, 0, -1])
def _set_up_meas_specs_for_testing(): q0, q1 = cirq.LineQubit.range(2) setting = cw.InitObsSetting(init_state=cirq.KET_ZERO(q0) * cirq.KET_ZERO(q1), observable=cirq.X(q0) * cirq.Y(q1)) meas_spec = _MeasurementSpec(max_setting=setting, circuit_params={ 'beta': 0.123, 'gamma': 0.456 }) bsa = cw.BitstringAccumulator( meas_spec, [], {q: i for i, q in enumerate(cirq.LineQubit.range(3))}) return bsa, meas_spec
def test_observable_measured_result(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') omr = cw.ObservableMeasuredResult( setting=cw.InitObsSetting( init_state=cirq.Z(a) * cirq.Z(b), observable=cirq.Y(a) * cirq.Y(b), ), mean=0, variance=5**2, repetitions=4, circuit_params={'phi': 52}, ) assert omr.stddev == 5 assert omr.observable == cirq.Y(a) * cirq.Y(b) assert omr.init_state == cirq.Z(a) * cirq.Z(b) cirq.testing.assert_equivalent_repr(omr) assert omr.as_dict() == { 'init_state': cirq.Z(a) * cirq.Z(b), 'observable': cirq.Y(a) * cirq.Y(b), 'mean': 0, 'variance': 25, 'repetitions': 4, 'param.phi': 52, } omr2 = dataclasses.replace( omr, circuit_params={ 'phi': 52, 'observable': 3.14, # this would be a bad but legal parameter name 'param.phi': -1, }, ) assert omr2.as_dict() == { 'init_state': cirq.Z(a) * cirq.Z(b), 'observable': cirq.Y(a) * cirq.Y(b), 'mean': 0, 'variance': 25, 'repetitions': 4, 'param.phi': 52, 'param.observable': 3.14, 'param.param.phi': -1, }
def test_observable_measured_result(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') omr = cw.ObservableMeasuredResult( setting=cw.InitObsSetting( init_state=cirq.Z(a) * cirq.Z(b), observable=cirq.Y(a) * cirq.Y(b), ), mean=0, variance=5**2, repetitions=4, circuit_params={}, ) assert omr.stddev == 5 assert omr.observable == cirq.Y(a) * cirq.Y(b) assert omr.init_state == cirq.Z(a) * cirq.Z(b) cirq.testing.assert_equivalent_repr(omr)
def test_measure_grouped_settings(with_circuit_sweep, checkpoint, tmpdir): qubits = cirq.LineQubit.range(1) (q, ) = qubits tests = [ (cirq.KET_ZERO, cirq.Z, 1), (cirq.KET_ONE, cirq.Z, -1), (cirq.KET_PLUS, cirq.X, 1), (cirq.KET_MINUS, cirq.X, -1), (cirq.KET_IMAG, cirq.Y, 1), (cirq.KET_MINUS_IMAG, cirq.Y, -1), ] if with_circuit_sweep: ss = cirq.Linspace('a', 0, 1, 12) else: ss = None if checkpoint: checkpoint_fn = f'{tmpdir}/obs.json' else: checkpoint_fn = None for init, obs, coef in tests: setting = cw.InitObsSetting( init_state=init(q), observable=obs(q), ) grouped_settings = {setting: [setting]} circuit = cirq.Circuit(cirq.I.on_each(*qubits)) results = cw.measure_grouped_settings( circuit=circuit, grouped_settings=grouped_settings, sampler=cirq.Simulator(), stopping_criteria=cw.RepetitionsStoppingCriteria( 1_000, repetitions_per_chunk=500), circuit_sweep=ss, checkpoint=CheckpointFileOptions(checkpoint=checkpoint, checkpoint_fn=checkpoint_fn), ) if with_circuit_sweep: for result in results: assert result.means() == [coef] else: (result, ) = results # one group assert result.means() == [coef]
def test_meas_specs_still_todo(): q0, q1 = cirq.LineQubit.range(2) setting = cw.InitObsSetting(init_state=cirq.KET_ZERO(q0) * cirq.KET_ZERO(q1), observable=cirq.X(q0) * cirq.Y(q1)) meas_spec = _MeasurementSpec( max_setting=setting, circuit_params={ 'beta': 0.123, 'gamma': 0.456, }, ) bsa = cw.BitstringAccumulator( meas_spec, [], {q: i for i, q in enumerate(cirq.LineQubit.range(3))}) # 1. before taking any data still_todo, reps = _check_meas_specs_still_todo( meas_specs=[meas_spec], accumulators={meas_spec: bsa}, desired_repetitions=1_000) assert still_todo == [meas_spec] assert reps == 1_000 # 2. After taking a mocked-out 997 shots. bsa.consume_results(np.zeros((997, 3), dtype=np.uint8)) still_todo, reps = _check_meas_specs_still_todo( meas_specs=[meas_spec], accumulators={meas_spec: bsa}, desired_repetitions=1_000) assert still_todo == [meas_spec] assert reps == 3 # 3. After taking the final 3 shots bsa.consume_results(np.zeros((reps, 3), dtype=np.uint8)) still_todo, reps = _check_meas_specs_still_todo( meas_specs=[meas_spec], accumulators={meas_spec: bsa}, desired_repetitions=1_000) assert still_todo == [] assert reps == 0
def test_subdivide_meas_specs(): qubits = cirq.LineQubit.range(2) q0, q1 = qubits setting = cw.InitObsSetting(init_state=cirq.KET_ZERO(q0) * cirq.KET_ZERO(q1), observable=cirq.X(q0) * cirq.Y(q1)) meas_spec = cw._MeasurementSpec( max_setting=setting, circuit_params={ 'beta': 0.123, 'gamma': 0.456, }, ) flippy_mspecs, repetitions = _subdivide_meas_specs( meas_specs=[meas_spec], repetitions=100_000, qubits=qubits, readout_symmetrization=True) fmspec1, fmspec2 = flippy_mspecs assert repetitions == 50_000 assert fmspec1.meas_spec == meas_spec assert fmspec2.meas_spec == meas_spec assert np.all(fmspec2.flips) assert not np.any(fmspec1.flips) assert list(fmspec1.param_tuples()) == [ ('0-Xf', 0), ('0-Yf', -0.5), ('0-Xi', 0), ('0-Yi', 0), ('1-Xf', 0.5), ('1-Yf', 0), ('1-Xi', 0), ('1-Yi', 0), ('beta', 0.123), ('gamma', 0.456), ]
def test_measure_grouped_settings(with_circuit_sweep): qubits = cirq.LineQubit.range(1) (q, ) = qubits tests = [ (cirq.KET_ZERO, cirq.Z, 1), (cirq.KET_ONE, cirq.Z, -1), (cirq.KET_PLUS, cirq.X, 1), (cirq.KET_MINUS, cirq.X, -1), (cirq.KET_IMAG, cirq.Y, 1), (cirq.KET_MINUS_IMAG, cirq.Y, -1), ] if with_circuit_sweep: ss = cirq.Linspace('a', 0, 1, 12) else: ss = None for init, obs, coef in tests: setting = cw.InitObsSetting( init_state=init(q), observable=obs(q), ) grouped_settings = {setting: [setting]} circuit = cirq.Circuit(cirq.I.on_each(*qubits)) results = cw.measure_grouped_settings( circuit=circuit, grouped_settings=grouped_settings, sampler=cirq.Simulator(), desired_repetitions=1_000, circuit_sweep=ss, ) if with_circuit_sweep: for result in results: assert result.means() == [coef] else: (result, ) = results # one group assert result.means() == [coef]
def test_bitstring_accumulator_equality(): et = cirq.testing.EqualsTester() bitstrings = np.array( [ [0, 0], [0, 1], [1, 0], [1, 1], ], dtype=np.uint8, ) chunksizes = np.asarray([4]) timestamps = np.asarray([datetime.datetime.now()]) a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') qubit_to_index = {a: 0, b: 1} obs = cirq.Z(a) * cirq.Z(b) * 10 setting = cw.InitObsSetting(init_state=cirq.Z(a) * cirq.Z(b), observable=obs) meas_spec = _MeasurementSpec(setting, {}) cirq.testing.assert_equivalent_repr( cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings.copy(), chunksizes=chunksizes.copy(), timestamps=timestamps.copy(), )) et.add_equality_group( cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings.copy(), chunksizes=chunksizes.copy(), timestamps=timestamps.copy(), ), cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings.copy(), chunksizes=chunksizes.copy(), timestamps=timestamps.copy(), ), ) time.sleep(1) timestamps = np.asarray([datetime.datetime.now()]) et.add_equality_group( cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings, chunksizes=chunksizes, timestamps=timestamps, )) et.add_equality_group( cw.BitstringAccumulator( meas_spec=_MeasurementSpec(setting, {'a': 2}), simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings, chunksizes=chunksizes, timestamps=timestamps, )) bitstrings = bitstrings.copy() bitstrings[0] = [1, 1] et.add_equality_group( cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings, chunksizes=chunksizes, timestamps=timestamps, )) chunksizes = np.asarray([2, 2]) timestamps = np.asarray(list(timestamps) * 2) et.add_equality_group( cw.BitstringAccumulator( meas_spec=meas_spec, simul_settings=[setting], qubit_to_index=qubit_to_index, bitstrings=bitstrings, chunksizes=chunksizes, timestamps=timestamps, ))