def test_measure_registers(): qasm = """OPENQASM 2.0; include "qelib1.inc"; qreg q1[3]; creg c1[3]; measure q1 -> c1; """ parser = QasmParser() q1_0 = cirq.NamedQubit('q1_0') q1_1 = cirq.NamedQubit('q1_1') q1_2 = cirq.NamedQubit('q1_2') expected_circuit = Circuit() expected_circuit.append( cirq.MeasurementGate(num_qubits=1, key='c1_0').on(q1_0)) expected_circuit.append( cirq.MeasurementGate(num_qubits=1, key='c1_1').on(q1_1)) expected_circuit.append( cirq.MeasurementGate(num_qubits=1, key='c1_2').on(q1_2)) parsed_qasm = parser.parse(qasm) assert parsed_qasm.supportedFormat assert parsed_qasm.qelib1Include ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit) assert parsed_qasm.qregs == {'q1': 3} assert parsed_qasm.cregs == {'c1': 3}
def test_invalid_measurement_gate(): with pytest.raises(ValueError, match='length'): _ = cg.gate_to_proto_dict( cirq.MeasurementGate(3, 'test', invert_mask=(True,)), (cirq.GridQubit(2, 3), cirq.GridQubit(3, 4))) with pytest.raises(ValueError, match='no qubits'): _ = cg.gate_to_proto_dict(cirq.MeasurementGate(1, 'test'), ())
def test_consistent_protocols(): for n in range(1, 5): gate = cirq.MeasurementGate(num_qubits=n, key='a') cirq.testing.assert_implements_consistent_protocols(gate) gate = cirq.MeasurementGate(num_qubits=n, key='a', qid_shape=(3, ) * n) cirq.testing.assert_implements_consistent_protocols(gate)
def test_measurement_channel(): np.testing.assert_allclose( cirq.kraus(cirq.MeasurementGate(1, 'a')), (np.array([[1, 0], [0, 0]]), np.array([[0, 0], [0, 1]])), ) # yapf: disable np.testing.assert_allclose( cirq.kraus(cirq.MeasurementGate(2, 'a')), (np.array([[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]]))) np.testing.assert_allclose( cirq.kraus(cirq.MeasurementGate(2, 'a', qid_shape=(2, 3))), (np.diag([1, 0, 0, 0, 0, 0]), np.diag([0, 1, 0, 0, 0, 0]), np.diag([0, 0, 1, 0, 0, 0]), np.diag([0, 0, 0, 1, 0, 0]), np.diag([0, 0, 0, 0, 1, 0]), np.diag([0, 0, 0, 0, 0, 1])))
def test_handles_measurement_gate(): q0, q1 = cirq.LineQubit.range(2) c_orig = cirq.Circuit.from_ops( cirq.X(q0)**0.25, cirq.H(q0), cirq.CZ(q0, q1), cirq.H(q0), cirq.X(q0)**0.125, cirq.MeasurementGate('m1')(q1), cirq.MeasurementGate('m0')(q0), ) c_opt = pauli_string_optimized_circuit(c_orig) cirq.testing.assert_allclose_up_to_global_phase( c_orig.to_unitary_matrix(), c_opt.to_unitary_matrix(), atol=1e-7, ) cirq.testing.assert_has_diagram( c_opt, """ 0: ───[Y]^-0.5───@───[Z]^(-1/8)───[X]^0.5───[Z]^0.5───M('m0')─── │ 1: ──────────────@───M('m1')──────────────────────────────────── """)
def bit_flip_circuit(flip0, flip1): q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(0, 1) g1, g2 = cg.ExpWGate(half_turns=flip0)(q1), cg.ExpWGate( half_turns=flip1)(q2) m1, m2 = cirq.MeasurementGate('q1')(q1), cirq.MeasurementGate('q2')(q2) circuit = cirq.Circuit() circuit.append([g1, g2, m1, m2]) return circuit
def test_measurement_channel(): np.testing.assert_allclose( cirq.channel(cirq.MeasurementGate(1)), (np.array([[1, 0], [0, 0]]), np.array([[0, 0], [0, 1]]))) np.testing.assert_allclose( cirq.channel(cirq.MeasurementGate(2)), (np.array([[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]])))
def test_passes_through_measurements(): q0, q1, q2 = cirq.LineQubit.range(3) circuit = cirq.Circuit.from_ops( cirq.MeasurementGate('m0')(q0), cirq.MeasurementGate('m1', invert_mask=(True, False))(q1, q2), ) c_orig = cirq.Circuit(circuit) cirq.ConvertToCzAndSingleGates().optimize_circuit(circuit) assert circuit == c_orig
def test_inverted_measurement_multiple_qubits(scheduler): circuit = cirq.Circuit.from_ops( cirq.MeasurementGate('a', invert_mask=(False, True))(Q1, Q2), cirq.MeasurementGate('b', invert_mask=(True, False))(Q1, Q2), cirq.MeasurementGate('c', invert_mask=(True, False))(Q2, Q1)) simulator = cg.XmonSimulator() result = run(simulator, circuit, scheduler) np.testing.assert_equal(result.measurements['a'], [[False, True]]) np.testing.assert_equal(result.measurements['b'], [[True, False]]) np.testing.assert_equal(result.measurements['c'], [[True, False]])
def test_measurement_full_invert_mask(): assert cirq.MeasurementGate(1, 'a').full_invert_mask() == (False, ) assert cirq.MeasurementGate(2, 'a', invert_mask=(False, True)).full_invert_mask() == ( False, True, ) assert cirq.MeasurementGate( 2, 'a', invert_mask=(True, )).full_invert_mask() == (True, False)
def test_run_no_sharing_few_qubits(scheduler): np.random.seed(0) circuit = basic_circuit() circuit.append( [cirq.MeasurementGate(key='a')(Q1), cirq.MeasurementGate(key='b')(Q2)]) simulator = cg.XmonSimulator(cg.XmonOptions(min_qubits_before_shard=0)) result = run(simulator, circuit, scheduler) np.testing.assert_equal(result.measurements['a'], [[True]]) np.testing.assert_equal(result.measurements['b'], [[False]])
def test_measurement_gate_diagram(): # Shows key. assert cirq.circuit_diagram_info(cirq.MeasurementGate(1)) == cirq.CircuitDiagramInfo(("M('')",)) assert cirq.circuit_diagram_info( cirq.MeasurementGate(1, key='test') ) == cirq.CircuitDiagramInfo(("M('test')",)) # Uses known qubit count. assert ( cirq.circuit_diagram_info( cirq.MeasurementGate(3), cirq.CircuitDiagramInfoArgs( known_qubits=None, known_qubit_count=3, use_unicode_characters=True, precision=None, qubit_map=None, ), ) == cirq.CircuitDiagramInfo(("M('')", 'M', 'M')) ) # Shows invert mask. assert cirq.circuit_diagram_info( cirq.MeasurementGate(2, invert_mask=(False, True)) ) == cirq.CircuitDiagramInfo(("M('')", "!M")) # Omits key when it is the default. a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure(a, b)), """ a: ───M─── │ b: ───M─── """, ) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure(a, b, invert_mask=(True,))), """ a: ───!M─── │ b: ───M──── """, ) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure(a, b, key='test')), """ a: ───M('test')─── │ b: ───M─────────── """, )
def test_validate_circuit_repeat_measurement_keys(): d = square_device(3, 3) circuit = cirq.Circuit() circuit.append([ cirq.MeasurementGate('a').on(cirq.GridQubit(0, 0)), cirq.MeasurementGate('a').on(cirq.GridQubit(0, 1)) ]) with pytest.raises(ValueError, message='Measurement key a repeated'): d.validate_circuit(circuit)
def test_measurement_multiple_measurements_qubit_order(scheduler): circuit = cirq.Circuit() measure_a = cirq.MeasurementGate('a') measure_b = cirq.MeasurementGate('b') circuit.append(cirq.X(Q1)) circuit.append([measure_a.on(Q1, Q2)]) circuit.append([measure_b.on(Q2, Q1)]) simulator = cg.XmonSimulator() result = run(simulator, circuit, scheduler) np.testing.assert_equal(result.measurements['a'], [[True, False]]) np.testing.assert_equal(result.measurements['b'], [[False, True]])
def test_measurement_qubit_count_vs_mask_length(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') c = cirq.NamedQubit('c') _ = cirq.MeasurementGate(invert_mask=(True, )).on(a) _ = cirq.MeasurementGate(invert_mask=(True, False)).on(a, b) _ = cirq.MeasurementGate(invert_mask=(True, False, True)).on(a, b, c) with pytest.raises(ValueError): _ = cirq.MeasurementGate(invert_mask=(True, False)).on(a) with pytest.raises(ValueError): _ = cirq.MeasurementGate(invert_mask=(True, False, True)).on(a, b)
def test_simulate_measurement_inversions(): q = cirq.NamedQubit('q') c = cirq.Circuit.from_ops( cirq.MeasurementGate(key='q', invert_mask=(True, )).on(q)) assert cirq.Simulator().simulate(c).measurements == {'q': np.array([True])} c = cirq.Circuit.from_ops( cirq.MeasurementGate(key='q', invert_mask=(False, )).on(q)) assert cirq.Simulator().simulate(c).measurements == { 'q': np.array([False]) }
def test_run(scheduler): np.random.seed(0) circuit = basic_circuit() circuit.append( [cirq.MeasurementGate(key='a')(Q1), cirq.MeasurementGate(key='b')(Q2)]) simulator = cg.XmonSimulator() result = run(simulator, circuit, scheduler) assert result.measurements['a'].dtype == bool assert result.measurements['b'].dtype == bool np.testing.assert_equal(result.measurements, {'a': [[False]], 'b': [[True]]})
def test_inverted_measurement(scheduler): circuit = cirq.Circuit.from_ops( cirq.MeasurementGate('a', invert_mask=(False,))(Q1), cirq.X(Q1), cirq.MeasurementGate('b', invert_mask=(False,))(Q1), cirq.MeasurementGate('c', invert_mask=(True,))(Q1), cirq.X(Q1), cirq.MeasurementGate('d', invert_mask=(True,))(Q1)) simulator = cg.XmonSimulator() result = run(simulator, circuit, scheduler) np.testing.assert_equal(result.measurements, {'a': [[False]], 'b': [[True]], 'c': [[False]], 'd': [[True]]})
def test_simulate_moment_steps(): np.random.seed(0) circuit = basic_circuit() circuit.append( [cirq.MeasurementGate(key='a')(Q1), cirq.MeasurementGate(key='b')(Q2)]) simulator = cg.XmonSimulator() results = [] for step in simulator.simulate_moment_steps(circuit): results.append(step) expected = [{}, {}, {}, {}, {'a': [False], 'b': [False]}] assert len(results) == len(expected) assert all(a.measurements == b for a, b in zip(results, expected))
def test_measurement_eq(): eq = cirq.testing.EqualsTester() eq.make_equality_group( lambda: cirq.MeasurementGate(1, 'a'), lambda: cirq.MeasurementGate(1, 'a', invert_mask=()), lambda: cirq.MeasurementGate(1, 'a', qid_shape=(2, )), ) eq.add_equality_group(cirq.MeasurementGate(1, 'a', invert_mask=(True, ))) eq.add_equality_group(cirq.MeasurementGate(1, 'a', invert_mask=(False, ))) eq.add_equality_group(cirq.MeasurementGate(1, 'b')) eq.add_equality_group(cirq.MeasurementGate(2, 'a')) eq.add_equality_group(cirq.MeasurementGate(3, 'a'), cirq.MeasurementGate(3, 'a', qid_shape=(2, 2, 2))) eq.add_equality_group(cirq.MeasurementGate(3, 'a', qid_shape=(1, 2, 3)))
def test_measure(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') # Empty application. with pytest.raises(ValueError): _ = cirq.measure() assert cirq.measure(a) == cirq.MeasurementGate(key='a').on(a) assert cirq.measure(a, b) == cirq.MeasurementGate(key='a,b').on(a, b) assert cirq.measure(b, a) == cirq.MeasurementGate(key='b,a').on(b, a) assert cirq.measure(a, key='b') == cirq.MeasurementGate(key='b').on(a) assert cirq.measure(a, invert_mask=(True, )) == cirq.MeasurementGate( key='a', invert_mask=(True, )).on(a)
def test_measurement_eq(): eq = cirq.testing.EqualsTester() eq.add_equality_group(cirq.MeasurementGate(1, ''), cirq.MeasurementGate(1, '', invert_mask=())) eq.add_equality_group(cirq.MeasurementGate(1, 'a')) eq.add_equality_group(cirq.MeasurementGate(1, 'a', invert_mask=(True,))) eq.add_equality_group(cirq.MeasurementGate(1, 'a', invert_mask=(False,))) eq.add_equality_group(cirq.MeasurementGate(1, 'b')) eq.add_equality_group(cirq.MeasurementGate(2, 'a')) eq.add_equality_group(cirq.MeasurementGate(2, '')) eq.add_equality_group(cirq.MeasurementGate(3, 'a'))
def test_validate_schedule_repeat_measurement_keys(): d = square_device(3, 3) s = cirq.Schedule(d, [ cirq.ScheduledOperation.op_at_on( cirq.MeasurementGate('a').on(cirq.GridQubit( 0, 0)), cirq.Timestamp(), d), cirq.ScheduledOperation.op_at_on( cirq.MeasurementGate('a').on(cirq.GridQubit( 0, 1)), cirq.Timestamp(), d), ]) with pytest.raises(ValueError, message='Measurement key a repeated'): d.validate_schedule(s)
def test_simulate_moment_steps_sample(): np.random.seed(0) circuit = cirq.Circuit.from_ops(cirq.X(Q1), cirq.MeasurementGate(key='a')(Q1), cirq.MeasurementGate(key='b')(Q2)) simulator = cg.XmonSimulator() for step in simulator.simulate_moment_steps(circuit, qubit_order=[Q1, Q2]): pass np.testing.assert_equal([[True]], step.sample([Q1])) np.testing.assert_equal([[True, False]], step.sample([Q1, Q2])) np.testing.assert_equal([[False]], step.sample([Q2])) np.testing.assert_equal([[True]] * 3, step.sample([Q1], 3)) np.testing.assert_equal([[True, False]] * 3, step.sample([Q1, Q2], 3)) np.testing.assert_equal([[False]] * 3, step.sample([Q2], 3))
def xmon_op_from_proto(proto: operations_pb2.Operation) -> cirq.Operation: """Convert the proto to the corresponding operation. See protos in api/google/v1 for specification of the protos. Args: proto: Operation proto. Returns: The operation. """ param = _parameterized_value_from_proto qubit = _qubit_from_proto if proto.HasField('exp_w'): exp_w = proto.exp_w return cirq.PhasedXPowGate( exponent=param(exp_w.half_turns), phase_exponent=param(exp_w.axis_half_turns), ).on(qubit(exp_w.target)) if proto.HasField('exp_z'): exp_z = proto.exp_z return cirq.Z(qubit(exp_z.target))**param(exp_z.half_turns) if proto.HasField('exp_11'): exp_11 = proto.exp_11 return cirq.CZ(qubit(exp_11.target1), qubit(exp_11.target2))**param(exp_11.half_turns) if proto.HasField('measurement'): meas = proto.measurement return cirq.MeasurementGate(num_qubits=len(meas.targets), key=meas.key, invert_mask=tuple(meas.invert_mask)).on( *[qubit(q) for q in meas.targets]) raise ValueError(f'invalid operation: {proto}')
def test_single_qubit_measurement_to_proto_convert_invert_mask(): gate = cirq.MeasurementGate(1, 'test', invert_mask=(True, )) proto = operations_pb2.Operation(measurement=operations_pb2.Measurement( targets=[operations_pb2.Qubit(row=2, col=3)], key='test', invert_mask=[True])) assert_proto_dict_convert(gate, proto, cirq.GridQubit(2, 3))
def test_measurement_keys_repeat(scheduler): circuit = cirq.Circuit() meas = cirq.MeasurementGate('a') circuit.append([meas.on(Q1), cirq.X.on(Q1), cirq.X.on(Q2), meas.on(Q2)]) simulator = cg.XmonSimulator() with pytest.raises(ValueError, message='Repeated Measurement key a'): run(simulator, circuit, scheduler)
def test_validate_schedule_errors(): d = square_device(2, 2, max_controls=3) s = cirq.Schedule(device=cirq.UnconstrainedDevice) q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) q10 = cirq.GridQubit(1, 0) q11 = cirq.GridQubit(1, 1) us = cirq.Duration(nanos=10**3) ms = cirq.Duration(nanos=10**6) msone = cirq.Timestamp(nanos=10**6) mstwo = cirq.Timestamp(nanos=2*10**6) msthree = cirq.Timestamp(nanos=3*10**6) for qubit in d.qubits: s.include(cirq.ScheduledOperation(cirq.Timestamp(nanos=0), 100*us, cirq.X.on(qubit))) s.include(cirq.ScheduledOperation(msone, 100*us, cirq.TOFFOLI.on(q00,q01,q10))) s.include(cirq.ScheduledOperation(mstwo, 100*us, cirq.ParallelGateOperation( cirq.X, [q00, q01]))) s.include(cirq.ScheduledOperation(mstwo, 100*us, cirq.ParallelGateOperation( cirq.Z, [q10, q11]))) for qubit in d.qubits: s.include(cirq.ScheduledOperation(msthree, 50*ms, cirq.GateOperation( cirq.MeasurementGate(1, qubit), [qubit]))) d.validate_schedule(s) s.include(cirq.ScheduledOperation(cirq.Timestamp(nanos=10**9), 100*us, cirq.X.on(q00))) with pytest.raises(ValueError, match="Non-measurement operation after " "measurement"): d.validate_schedule(s)
def test_validate_operation_errors(): d = square_device(3, 3) class bad_op(cirq.Operation): def bad_op(self): pass def qubits(self): pass def with_qubits(self, new_qubits): pass with pytest.raises(ValueError, match="Unsupported operation"): d.validate_operation(bad_op()) not_on_device_op = cirq.parallel_gate_op( cirq.X, *[cirq.GridQubit(row, col) for col in range(4) for row in range(4)] ) with pytest.raises(ValueError, match="Qubit not on device"): d.validate_operation(not_on_device_op) with pytest.raises(ValueError, match="Too many qubits acted on in parallel by"): d.validate_operation(cirq.CCX.on(*d.qubit_list()[0:3])) with pytest.raises(ValueError, match="are too far away"): d.validate_operation(cirq.CZ.on(cirq.GridQubit(0, 0), cirq.GridQubit(2, 2))) with pytest.raises(ValueError, match="Unsupported operation"): d.validate_operation(cirq.parallel_gate_op(cirq.Z, *d.qubits)) with pytest.raises(ValueError, match="Unsupported operation"): d.validate_operation(cirq.parallel_gate_op(cirq.X, *d.qubit_list()[1:])) with pytest.raises(ValueError, match="Unsupported operation"): d.validate_operation( cirq.ParallelGate(cirq.MeasurementGate(1, key='a'), 4)(*d.qubit_list()[:4]) )
def test_eval_repr(key): # Basic safeguard against repr-inequality. op = cirq.GateOperation( gate=cirq.MeasurementGate(1, key), qubits=[cirq.GridQubit(0, 1)], ) cirq.testing.assert_equivalent_repr(op)