def test_convert_to_cz_preserving_moment_structure(): q = cirq.LineQubit.range(5) op = lambda q0, q1: cirq.H(q1).controlled_by(q0) c_orig = cirq.Circuit( cirq.Moment(cirq.X(q[2])), cirq.Moment(op(q[0], q[1]), op(q[2], q[3])), cirq.Moment(op(q[2], q[1]), op(q[4], q[3])), cirq.Moment(op(q[1], q[2]), op(q[3], q[4])), cirq.Moment(op(q[3], q[2]), op(q[1], q[0])), cirq.measure(*q[:2], key="m"), cirq.X(q[2]).with_classical_controls("m"), cirq.CZ(*q[3:]).with_classical_controls("m"), ) c_new = cirq.optimize_for_target_gateset(c_orig, gateset=cirq.CZTargetGateset()) assert c_orig[-2:] == c_new[-2:] c_orig, c_new = c_orig[:-2], c_new[:-2] cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( c_orig, c_new, atol=1e-6) assert all( (all_gates_of_type(m, cirq.Gateset(cirq.AnyUnitaryGateFamily(1))) or all_gates_of_type(m, cirq.Gateset(cirq.CZ))) for m in c_new) c_new = cirq.optimize_for_target_gateset( c_orig, gateset=cirq.CZTargetGateset(allow_partial_czs=True), ignore_failures=False) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( c_orig, c_new, atol=1e-6) assert all( (all_gates_of_type(m, cirq.Gateset(cirq.AnyUnitaryGateFamily(1))) or all_gates_of_type(m, cirq.Gateset(cirq.CZPowGate))) for m in c_new)
def test_griddevice_metadata_bad_durations(): qubits = tuple(cirq.GridQubit.rect(1, 2)) gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate) invalid_duration = { cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1), cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=1), } with pytest.raises(ValueError, match="ZPowGate"): cirq.GridDeviceMetadata([qubits], gateset, gate_durations=invalid_duration)
def test_to_proto_empty(): spec = grid_device.create_device_specification_proto( # Qubits are always expected to be set qubits=[cirq.GridQubit(0, i) for i in range(5)], pairs=[], gateset=cirq.Gateset(), gate_durations=None, ) device = cirq_google.GridDevice.from_proto(spec) assert len(device.metadata.qubit_set) == 5 assert len(device.metadata.qubit_pairs) == 0 assert device.metadata.gateset == cirq.Gateset() assert device.metadata.gate_durations is None
def test_repr(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate) duration = { cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1), cirq.Gateset(cirq.YPowGate): cirq.Duration(picos=3), cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=2), } metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration) cirq.testing.assert_equivalent_repr(metadata)
def test_griddevice_json_load(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate) duration = { cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1), cirq.Gateset(cirq.YPowGate): cirq.Duration(picos=2), cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=3), } metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration) rep_str = cirq.to_json(metadata) assert metadata == cirq.read_json(json_text=rep_str)
def __init__( self, qubits: List[cirq.Qid], gate_definitions: Dict[Type[cirq.Gate], List[_GateDefinition]], ): """Constructor for SerializableDevice using python objects. Note that the preferred method of constructing this object is through the static from_proto() call. Args: qubits: A list of valid Qid for the device. gate_definitions: Maps cirq gates to device properties for that gate. """ self.qubits = qubits self.gate_definitions = gate_definitions self._metadata = cirq.GridDeviceMetadata( qubit_pairs=[(pair[0], pair[1]) for gate_defs in gate_definitions.values() for gate_def in gate_defs if gate_def.number_of_qubits == 2 for pair in gate_def.target_set if len(pair) == 2 and pair[0] < pair[1]], gateset=cirq.Gateset(*[ g for g in gate_definitions.keys() if isinstance(g, (cirq.Gate, type(cirq.Gate))) ]), gate_durations=None, )
def __init__( self, control_radius: float, qubits: Sequence[Union[ThreeDQubit, GridQubit, LineQubit]]) -> None: """Initializes a device with some qubits. Args: control_radius: the maximum distance between qubits for a controlled gate. Distance is measured in units of the coordinates passed into the qubit constructor. qubits: Qubits on the device, identified by their x, y, z position. Must be of type ThreeDQubit, TwoDQubit, LineQubit or GridQubit. Raises: ValueError: if the wrong qubit type is provided or if invalid parameter is provided for control_radius.""" super().__init__(qubits) if not control_radius >= 0: raise ValueError( 'Control_radius needs to be a non-negative float.') if len(self.qubits) > 1: if control_radius > 3.0 * self.minimal_distance(): raise ValueError('Control_radius cannot be larger than 3 times' ' the minimal distance between qubits.') self.control_radius = control_radius self.gateset = PasqalGateset(include_additional_controlled_ops=False) self.controlled_gateset = cirq.Gateset( cirq.AnyIntegerPowerGateFamily(cirq.CZPowGate))
def test_griddevice_self_loop(): bad_pairs = [ (cirq.GridQubit(0, 0), cirq.GridQubit(0, 0)), (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), ] with pytest.raises(ValueError, match='Self loop'): _ = cirq.GridDeviceMetadata(bad_pairs, cirq.Gateset(cirq.XPowGate))
def test_griddevice_metadata(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] isolated_qubits = [cirq.GridQubit(9, 9), cirq.GridQubit(10, 10)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZ) metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, all_qubits=qubits + isolated_qubits) expected_pairings = frozenset({ (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), (cirq.GridQubit(0, 1), cirq.GridQubit(0, 2)), (cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 2), cirq.GridQubit(1, 2)), (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), (cirq.GridQubit(1, 1), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), }) assert metadata.qubit_set == frozenset(qubits + isolated_qubits) assert metadata.qubit_pairs == expected_pairings assert metadata.gateset == gateset expected_graph = nx.Graph() expected_graph.add_nodes_from(sorted(list(qubits + isolated_qubits))) expected_graph.add_edges_from(sorted(list(expected_pairings)), directed=False) assert metadata.nx_graph.edges() == expected_graph.edges() assert metadata.nx_graph.nodes() == expected_graph.nodes() assert metadata.gate_durations is None assert metadata.isolated_qubits == frozenset(isolated_qubits)
def __init__(self, qubits: Union[Sequence[cirq.LineQubit], int], atol=1e-8): """Construct the device. Args: qubits: The qubits upon which this device acts or the number of qubits. If the number of qubits, then the qubits will be `cirq.LineQubit`s from 0 to this number minus one. atol: The absolute tolerance used for gate calculations and decompositions. """ if isinstance(qubits, int): self.qubits = frozenset(cirq.LineQubit.range(qubits)) else: self.qubits = frozenset(qubits) self.atol = atol self.gateset = cirq.Gateset( cirq.H, cirq.CNOT, cirq.SWAP, cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.XXPowGate, cirq.YYPowGate, cirq.ZZPowGate, cirq.MeasurementGate, unroll_circuit_op=False, accept_global_phase=False, )
def __init__( self, qubits: List[cirq.Qid], gate_definitions: Dict[_GateOrFrozenCircuitTypes, List[_GateDefinition]], ): """Constructor for SerializableDevice using python objects. Note that the preferred method of constructing this object is through the static from_proto() call. Args: qubits: A list of valid Qid for the device. gate_definitions: Maps cirq gates to device properties for that gate. """ self.qubits = qubits self.gate_definitions = gate_definitions has_subcircuit_support: bool = cirq.FrozenCircuit in gate_definitions self._metadata = cirq.GridDeviceMetadata( qubit_pairs=[(pair[0], pair[1]) for gate_defs in gate_definitions.values() for gate_def in gate_defs if gate_def.number_of_qubits == 2 for pair in gate_def.target_set if len(pair) == 2 and pair[0] < pair[1]], gateset=cirq.Gateset( *(g for g in gate_definitions.keys() if issubclass(g, cirq.Gate)), cirq.GlobalPhaseGate, unroll_circuit_op=has_subcircuit_support, ), gate_durations=None, )
def test_device_metadata(): d = square_device(3, 3) assert d.metadata.gateset == cirq.Gateset( cirq.CZPowGate, cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate, cirq.PhasedXZGate, cirq.MeasurementGate, cirq.ZPowGate, cirq.GlobalPhaseGate, ) assert d.metadata.qubit_pairs == frozenset( { frozenset((cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))), frozenset((cirq.GridQubit(0, 1), cirq.GridQubit(1, 1))), frozenset((cirq.GridQubit(2, 0), cirq.GridQubit(2, 1))), frozenset((cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))), frozenset((cirq.GridQubit(0, 2), cirq.GridQubit(1, 2))), frozenset((cirq.GridQubit(1, 0), cirq.GridQubit(2, 0))), frozenset((cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))), frozenset((cirq.GridQubit(1, 1), cirq.GridQubit(2, 1))), frozenset((cirq.GridQubit(1, 1), cirq.GridQubit(1, 2))), frozenset((cirq.GridQubit(0, 1), cirq.GridQubit(0, 2))), frozenset((cirq.GridQubit(2, 1), cirq.GridQubit(2, 2))), frozenset((cirq.GridQubit(1, 2), cirq.GridQubit(2, 2))), } )
def test_metadata_correct(): qubits = cirq.GridQubit.rect(2, 3, left=1, top=1) pairs = [ (qubits[0], qubits[1]), (qubits[0], qubits[3]), (qubits[1], qubits[4]), (qubits[4], qubits[5]), ] device_proto = cgdk.create_device_proto_for_qubits( qubits=qubits, pairs=pairs, gate_sets=[cg.FSIM_GATESET]) device = cgdk.SerializableDevice.from_proto(device_proto, gate_sets=[cg.FSIM_GATESET]) assert device.metadata.qubit_pairs == frozenset( {frozenset(p) for p in pairs}) assert device.metadata.gateset == cirq.Gateset( cirq.FSimGate, cirq.ISwapPowGate, cirq.CZPowGate, cirq.PhasedXPowGate, cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.PhasedXZGate, cirq.MeasurementGate, cirq.WaitGate, cirq.GlobalPhaseGate, )
def __init__( self, measurement_duration: cirq.DURATION_LIKE, exp_w_duration: cirq.DURATION_LIKE, exp_11_duration: cirq.DURATION_LIKE, qubits: Iterable[cirq.GridQubit], ) -> None: """Initializes the description of an xmon device. Args: measurement_duration: The maximum duration of a measurement. exp_w_duration: The maximum duration of an ExpW operation. exp_11_duration: The maximum duration of an ExpZ operation. qubits: Qubits on the device, identified by their x, y location. """ self._measurement_duration = cirq.Duration(measurement_duration) self._exp_w_duration = cirq.Duration(exp_w_duration) self._exp_z_duration = cirq.Duration(exp_11_duration) self.qubits = frozenset(qubits) self._metadata = cirq.GridDeviceMetadata( [(q0, q1) for q0 in self.qubits for q1 in self.qubits if q0.is_adjacent(q1)], cirq.Gateset( cirq.CZPowGate, cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate, cirq.PhasedXZGate, cirq.MeasurementGate, cirq.ZPowGate, cirq.GlobalPhaseGate, ), None, )
def test_grid_device_from_proto(): grid_qubits, spec = _create_device_spec_with_horizontal_couplings() device = cirq_google.GridDevice.from_proto(spec) assert len(device.metadata.qubit_set) == len(grid_qubits) assert device.metadata.qubit_set == frozenset(grid_qubits) assert all( frozenset((cirq.GridQubit(row, 0), cirq.GridQubit(row, 1))) in device.metadata.qubit_pairs for row in range(GRID_HEIGHT) ) assert device.metadata.gateset == cirq.Gateset( cirq_google.FSimGateFamily(gates_to_accept=[cirq_google.SYC]), cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP]), cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV]), cirq_google.FSimGateFamily(gates_to_accept=[cirq.CZ]), cirq.ops.phased_x_z_gate.PhasedXZGate, cirq.ops.common_gates.XPowGate, cirq.ops.common_gates.YPowGate, cirq.ops.phased_x_gate.PhasedXPowGate, cirq.GateFamily( cirq.ops.common_gates.ZPowGate, tags_to_ignore=[cirq_google.PhysicalZTag()] ), cirq.GateFamily( cirq.ops.common_gates.ZPowGate, tags_to_accept=[cirq_google.PhysicalZTag()] ), cirq_google.experimental.ops.coupler_pulse.CouplerPulse, cirq.ops.measurement_gate.MeasurementGate, cirq.ops.wait_gate.WaitGate, ) assert tuple(device.metadata.compilation_target_gatesets) == ( cirq.CZTargetGateset(), cirq_google.SycamoreTargetGateset(), cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True), ) base_duration = cirq.Duration(picos=1_000) assert device.metadata.gate_durations == { cirq_google.FSimGateFamily(gates_to_accept=[cirq_google.SYC]): base_duration * 0, cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP]): base_duration * 1, cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV]): base_duration * 2, cirq_google.FSimGateFamily(gates_to_accept=[cirq.CZ]): base_duration * 3, cirq.GateFamily(cirq.ops.phased_x_z_gate.PhasedXZGate): base_duration * 4, cirq.GateFamily(cirq.ops.common_gates.XPowGate): base_duration * 4, cirq.GateFamily(cirq.ops.common_gates.YPowGate): base_duration * 4, cirq.GateFamily(cirq.ops.phased_x_gate.PhasedXPowGate): base_duration * 4, cirq.GateFamily( cirq.ops.common_gates.ZPowGate, tags_to_ignore=[cirq_google.PhysicalZTag()] ): base_duration * 5, cirq.GateFamily( cirq.ops.common_gates.ZPowGate, tags_to_accept=[cirq_google.PhysicalZTag()] ): base_duration * 6, cirq.GateFamily(cirq_google.experimental.ops.coupler_pulse.CouplerPulse): base_duration * 7, cirq.GateFamily(cirq.ops.measurement_gate.MeasurementGate): base_duration * 8, cirq.GateFamily(cirq.ops.wait_gate.WaitGate): base_duration * 9, }
def _build_gateset_and_gate_durations( proto: v2.device_pb2.DeviceSpecification, ) -> Tuple[cirq.Gateset, Dict[cirq.GateFamily, cirq.Duration]]: """Extracts gate set and gate duration information from the given DeviceSpecification proto.""" gates_list: List[Union[Type[cirq.Gate], cirq.Gate, cirq.GateFamily]] = [] gate_durations: Dict[cirq.GateFamily, cirq.Duration] = {} # TODO(#5050) Describe how to add/remove gates. for gate_spec in proto.valid_gates: gate_name = gate_spec.WhichOneof('gate') cirq_gates: List[Union[Type[cirq.Gate], cirq.Gate, cirq.GateFamily]] = [] if gate_name == 'syc': cirq_gates = [ops.FSimGateFamily(gates_to_accept=[ops.SYC])] elif gate_name == 'sqrt_iswap': cirq_gates = [ops.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP])] elif gate_name == 'sqrt_iswap_inv': cirq_gates = [ops.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV])] elif gate_name == 'cz': cirq_gates = [ops.FSimGateFamily(gates_to_accept=[cirq.CZ])] elif gate_name == 'phased_xz': cirq_gates = [cirq.PhasedXZGate, cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate] elif gate_name == 'virtual_zpow': cirq_gates = [cirq.GateFamily(cirq.ZPowGate, tags_to_ignore=[ops.PhysicalZTag()])] elif gate_name == 'physical_zpow': cirq_gates = [cirq.GateFamily(cirq.ZPowGate, tags_to_accept=[ops.PhysicalZTag()])] elif gate_name == 'coupler_pulse': cirq_gates = [experimental_ops.CouplerPulse] elif gate_name == 'meas': cirq_gates = [cirq.MeasurementGate] elif gate_name == 'wait': cirq_gates = [cirq.WaitGate] else: # coverage: ignore warnings.warn( f"The DeviceSpecification contains the gate '{gate_name}' which is not recognized" " by Cirq and will be ignored. This may be due to an out-of-date Cirq version.", UserWarning, ) continue gates_list.extend(cirq_gates) # TODO(#5050) Allow different gate representations of the same gate to be looked up in # gate_durations. for g in cirq_gates: if not isinstance(g, cirq.GateFamily): g = cirq.GateFamily(g) gate_durations[g] = cirq.Duration(picos=gate_spec.gate_duration_picos) # TODO(#4833) Add identity gate support # TODO(#5050) Add GlobalPhaseGate support return cirq.Gateset(*gates_list), gate_durations
def test_convert_to_sqrt_iswap_preserving_moment_structure(): q = cirq.LineQubit.range(5) op = lambda q0, q1: cirq.H(q1).controlled_by(q0) c_orig = cirq.Circuit( cirq.Moment(cirq.X(q[2])), cirq.Moment(op(q[0], q[1]), op(q[2], q[3])), cirq.Moment(op(q[2], q[1]), op(q[4], q[3])), cirq.Moment(op(q[1], q[2]), op(q[3], q[4])), cirq.Moment(op(q[3], q[2]), op(q[1], q[0])), cirq.measure(*q[:2], key="m"), cirq.X(q[2]).with_classical_controls("m"), cirq.CZ(*q[3:]).with_classical_controls("m"), ) # Classically controlled operations are not part of the gateset, so failures should be ignored # during compilation. c_new = cirq.optimize_for_target_gateset( c_orig, gateset=cirq.SqrtIswapTargetGateset(), ignore_failures=True ) assert c_orig[-2:] == c_new[-2:] c_orig, c_new = c_orig[:-2], c_new[:-2] cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(c_orig, c_new, atol=1e-6) assert all( ( all_gates_of_type(m, cirq.Gateset(cirq.PhasedXZGate)) or all_gates_of_type(m, cirq.Gateset(cirq.SQRT_ISWAP)) ) for m in c_new ) c_new = cirq.optimize_for_target_gateset( c_orig, gateset=cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True), ignore_failures=False ) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(c_orig, c_new, atol=1e-6) assert all( ( all_gates_of_type(m, cirq.Gateset(cirq.PhasedXZGate)) or all_gates_of_type(m, cirq.Gateset(cirq.SQRT_ISWAP_INV)) ) for m in c_new )
def test_griddevice_metadata_bad_isolated(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] fewer_qubits = [cirq.GridQubit(0, 0)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZ) with pytest.raises(ValueError, match='node_set'): _ = cirq.GridDeviceMetadata(qubit_pairs, gateset, all_qubits=fewer_qubits)
def test_griddevice_json_load_with_defaults(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZ) # Don't set parameters with default values metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset) rep_str = cirq.to_json(metadata) assert metadata == cirq.read_json(json_text=rep_str)
def test_decompose_operations_raises_on_stuck(): c_orig = cirq.Circuit(cirq.X(cirq.NamedQubit("q")).with_tags("ignore")) gateset = cirq.Gateset(cirq.Y) with pytest.raises(ValueError, match="Unable to convert"): _ = _decompose_operations_to_target_gateset(c_orig, gateset=gateset, ignore_failures=False) # Gates marked with a no-compile tag are completely ignored. c_new = _decompose_operations_to_target_gateset( c_orig, context=cirq.TransformerContext(tags_to_ignore=("ignore",)), gateset=gateset, ignore_failures=False, ) cirq.testing.assert_same_circuits(c_orig, c_new)
def test_sycamore_metadata(): assert len(cirq_google.Sycamore.metadata.qubit_pairs) == 88 assert len(cirq_google.Sycamore23.metadata.qubit_pairs) == 32 assert cirq_google.Sycamore.metadata.gateset == cirq.Gateset( cirq.FSimGate, cirq.ISwapPowGate, cirq.PhasedXPowGate, cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.PhasedXZGate, cirq.MeasurementGate, cirq.WaitGate, )
def __init__(self, qubits: Sequence[cirq.Qid]) -> None: """Initializes a device with some qubits. Args: qubits (NamedQubit): Qubits on the device, exclusively unrelated to a physical position. Raises: TypeError: If the wrong qubit type is provided. ValueError: If the number of qubits is greater than the devices maximum. """ if len(qubits) > 0: q_type = type(qubits[0]) for q in qubits: if not isinstance(q, self.supported_qubit_type): raise TypeError('Unsupported qubit type: {!r}. This device ' 'supports qubit types: {}'.format( q, self.supported_qubit_type)) if not type(q) is q_type: raise TypeError("All qubits must be of same type.") if len(qubits) > self.maximum_qubit_number: raise ValueError('Too many qubits. {} accepts at most {} ' 'qubits.'.format(type(self), self.maximum_qubit_number)) self.gateset = cirq.Gateset( cirq.ParallelGateFamily(cirq.H), cirq.ParallelGateFamily(cirq.PhasedXPowGate), cirq.ParallelGateFamily(cirq.XPowGate), cirq.ParallelGateFamily(cirq.YPowGate), cirq.ParallelGateFamily(cirq.ZPowGate), cirq.AnyIntegerPowerGateFamily(cirq.CNotPowGate), cirq.AnyIntegerPowerGateFamily(cirq.CCNotPowGate), cirq.AnyIntegerPowerGateFamily(cirq.CZPowGate), cirq.AnyIntegerPowerGateFamily(cirq.CCZPowGate), cirq.IdentityGate, cirq.MeasurementGate, unroll_circuit_op=False, accept_global_phase_op=False, ) self.qubits = qubits self._metadata = cirq.DeviceMetadata( qubits, nx.from_edgelist([(a, b) for a in qubits for b in qubits if a != b]))
def test_griddevice_metadata_equality(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate) duration = { cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1), cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=3), cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=2), } duration2 = { cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=10), cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=13), cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=12), } isolated_qubits = [cirq.GridQubit(9, 9)] metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration) metadata2 = cirq.GridDeviceMetadata(qubit_pairs[:2], gateset, gate_durations=duration) metadata3 = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=None) metadata4 = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration2) metadata5 = cirq.GridDeviceMetadata(reversed(qubit_pairs), gateset, gate_durations=duration) metadata6 = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration, all_qubits=qubits + isolated_qubits) eq = cirq.testing.EqualsTester() eq.add_equality_group(metadata) eq.add_equality_group(metadata2) eq.add_equality_group(metadata3) eq.add_equality_group(metadata4) eq.add_equality_group(metadata6) assert metadata == metadata5
def test_griddevice_metadata(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] isolated_qubits = [cirq.GridQubit(9, 9), cirq.GridQubit(10, 10)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZ) gate_durations = { cirq.GateFamily(cirq.XPowGate): 1_000, cirq.GateFamily(cirq.YPowGate): 1_000, cirq.GateFamily(cirq.ZPowGate): 1_000, # omitting cirq.CZ } target_gatesets = (cirq.CZTargetGateset(), ) metadata = cirq.GridDeviceMetadata( qubit_pairs, gateset, gate_durations=gate_durations, all_qubits=qubits + isolated_qubits, compilation_target_gatesets=target_gatesets, ) expected_pairings = frozenset({ frozenset((cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))), frozenset((cirq.GridQubit(0, 1), cirq.GridQubit(0, 2))), frozenset((cirq.GridQubit(0, 1), cirq.GridQubit(1, 1))), frozenset((cirq.GridQubit(0, 2), cirq.GridQubit(1, 2))), frozenset((cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))), frozenset((cirq.GridQubit(1, 1), cirq.GridQubit(1, 2))), frozenset((cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))), }) assert metadata.qubit_set == frozenset(qubits + isolated_qubits) assert metadata.qubit_pairs == expected_pairings assert metadata.gateset == gateset expected_graph = nx.Graph() expected_graph.add_nodes_from(sorted(list(qubits + isolated_qubits))) expected_graph.add_edges_from(sorted(list(expected_pairings)), directed=False) assert metadata.nx_graph.edges() == expected_graph.edges() assert metadata.nx_graph.nodes() == expected_graph.nodes() assert metadata.gate_durations == gate_durations assert metadata.isolated_qubits == frozenset(isolated_qubits) assert metadata.compilation_target_gatesets == target_gatesets
def test_to_proto(): device_info, expected_spec = _create_device_spec_with_horizontal_couplings( ) # The set of gates in gate_durations are consistent with what's generated in # _create_device_spec_with_horizontal_couplings() base_duration = cirq.Duration(picos=1_000) gate_durations = { cirq.GateFamily(cirq_google.SYC): base_duration * 0, cirq.GateFamily(cirq.SQRT_ISWAP): base_duration * 1, cirq.GateFamily(cirq.SQRT_ISWAP_INV): base_duration * 2, cirq.GateFamily(cirq.CZ): base_duration * 3, cirq.GateFamily(cirq.ops.phased_x_z_gate.PhasedXZGate): base_duration * 4, cirq.GateFamily(cirq.ops.common_gates.ZPowGate, tags_to_ignore=[cirq_google.PhysicalZTag()]): base_duration * 5, cirq.GateFamily(cirq.ops.common_gates.ZPowGate, tags_to_accept=[cirq_google.PhysicalZTag()]): base_duration * 6, cirq.GateFamily(cirq_google.experimental.ops.coupler_pulse.CouplerPulse): base_duration * 7, cirq.GateFamily(cirq.ops.measurement_gate.MeasurementGate): base_duration * 8, cirq.GateFamily(cirq.ops.wait_gate.WaitGate): base_duration * 9, } spec = grid_device.create_device_specification_proto( qubits=device_info.grid_qubits, pairs=device_info.qubit_pairs, gateset=cirq.Gateset(*gate_durations.keys()), gate_durations=gate_durations, ) assert text_format.MessageToString(spec) == text_format.MessageToString( expected_spec)
def test_metadata_correct(): # Deprecations: cirq_google.SerializableDevice, well-known cirq_google SerializableGateSets # (e.g. cirq_google.SYC_GATESET) and # cirq_google.devices.known_devices.create_device_proto_for_qubits with cirq.testing.assert_deprecated( 'Use cirq_google.GridDevice', 'SerializableGateSet', 'create_device_specification_proto()` can be used', deadline='v0.16', count=5, ): qubits = cirq.GridQubit.rect(2, 3, left=1, top=1) pairs = [ (qubits[0], qubits[1]), (qubits[0], qubits[3]), (qubits[1], qubits[4]), (qubits[4], qubits[5]), ] device_proto = cgdk.create_device_proto_for_qubits( qubits=qubits, pairs=pairs, gate_sets=[cg.FSIM_GATESET]) device = cg.SerializableDevice.from_proto(device_proto, gate_sets=[cg.FSIM_GATESET]) assert device.metadata.qubit_pairs == frozenset( {frozenset(p) for p in pairs}) assert device.metadata.gateset == cirq.Gateset( cirq.FSimGate, cirq.ISwapPowGate, cirq.CZPowGate, cirq.PhasedXPowGate, cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.PhasedXZGate, cirq.MeasurementGate, cirq.WaitGate, cirq.GlobalPhaseGate, )
def test_repr(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZ) duration = { cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1), cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=3), cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=2), cirq.GateFamily(cirq.CZ): cirq.Duration(nanos=4), } isolated_qubits = [cirq.GridQubit(9, 9)] target_gatesets = [cirq.CZTargetGateset()] metadata = cirq.GridDeviceMetadata( qubit_pairs, gateset, gate_durations=duration, all_qubits=qubits + isolated_qubits, compilation_target_gatesets=target_gatesets, ) cirq.testing.assert_equivalent_repr(metadata)
def test_griddevice_json_load(): qubits = cirq.GridQubit.rect(2, 3) qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)] gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZ) duration = { cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1), cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=2), cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=3), cirq.GateFamily(cirq.CZ): cirq.Duration(nanos=4), } isolated_qubits = [cirq.GridQubit(9, 9), cirq.GridQubit(10, 10)] target_gatesets = [cirq.CZTargetGateset()] metadata = cirq.GridDeviceMetadata( qubit_pairs, gateset, gate_durations=duration, all_qubits=qubits + isolated_qubits, compilation_target_gatesets=target_gatesets, ) rep_str = cirq.to_json(metadata) assert metadata == cirq.read_json(json_text=rep_str)
def test_decompose_operations_to_target_gateset(): q = cirq.LineQubit.range(2) c_orig = cirq.Circuit( cirq.T(q[0]), cirq.SWAP(*q), cirq.T(q[0]), cirq.SWAP(*q).with_tags("ignore"), cirq.measure(q[0], key="m"), cirq.X(q[1]).with_classical_controls("m"), cirq.Moment(cirq.T.on_each(*q)), cirq.SWAP(*q), cirq.T.on_each(*q), ) gateset = cirq.Gateset(cirq.H, cirq.CNOT) decomposer = ( lambda op, _: cirq.H(op.qubits[0]) if cirq.has_unitary(op) and cirq.num_qubits(op) == 1 else NotImplemented ) context = cirq.TransformerContext(tags_to_ignore=("ignore",)) c_new = _decompose_operations_to_target_gateset( c_orig, gateset=gateset, decomposer=decomposer, context=context ) cirq.testing.assert_has_diagram( c_new, ''' 0: ───H───@───X───@───H───×['ignore']───M───────H───@───X───@───H─── │ │ │ │ ║ │ │ │ 1: ───────X───@───X───────×─────────────╫───X───H───X───@───X───H─── ║ ║ m: ═════════════════════════════════════@═══^═══════════════════════''', ) with pytest.raises(ValueError, match="Unable to convert"): _ = _decompose_operations_to_target_gateset( c_orig, gateset=gateset, decomposer=decomposer, context=context, ignore_failures=False )
def test_gateset_contains_with_tags(): tag = "PhysicalZTag" gf_accept = cirq.GateFamily(cirq.ZPowGate, tags_to_accept=[tag]) gf_ignore = cirq.GateFamily(cirq.ZPowGate, tags_to_ignore=[tag]) op = cirq.Z(q) op_with_tag = cirq.Z(q).with_tags(tag) # Only tags to ignore. assert op in cirq.Gateset(gf_ignore) assert op_with_tag not in cirq.Gateset(gf_ignore) # Only tags to accept assert op not in cirq.Gateset(gf_accept) assert op_with_tag in cirq.Gateset(gf_accept) # Both tags to accept and tags to ignore assert op in cirq.Gateset(gf_accept, gf_ignore) assert op_with_tag in cirq.Gateset(gf_accept, gf_ignore)