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 assert_optimization_not_broken(circuit: cirq.Circuit): c_new = cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset()) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, c_new, atol=1e-6) c_new = cirq.optimize_for_target_gateset( circuit, gateset=cirq.CZTargetGateset(allow_partial_czs=True)) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, c_new, atol=1e-6)
def test_unsupported_gate(): class UnsupportedDummy(cirq.testing.TwoQubitGate): pass q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit(UnsupportedDummy()(q0, q1)) assert circuit == cirq.optimize_for_target_gateset( circuit, gateset=cirq.CZTargetGateset()) with pytest.raises(ValueError, match='Unable to convert'): _ = cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset(), ignore_failures=False)
def assert_optimizes( before: cirq.Circuit, expected: cirq.Circuit, additional_gates: Optional[Sequence[Type[cirq.Gate]]] = None, ): if additional_gates is None: gateset = cirq.CZTargetGateset() else: gateset = cirq.CZTargetGateset(additional_gates=additional_gates) cirq.testing.assert_same_circuits( cirq.optimize_for_target_gateset(before, gateset=gateset, ignore_failures=False), expected)
def test_composite_gates_without_matrix(): class CompositeDummy(cirq.SingleQubitGate): def _decompose_(self, qubits): yield cirq.X(qubits[0]) yield cirq.Y(qubits[0])**0.5 class CompositeDummy2(cirq.testing.TwoQubitGate): def _decompose_(self, qubits): yield cirq.CZ(qubits[0], qubits[1]) yield CompositeDummy()(qubits[1]) q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( CompositeDummy()(q0), CompositeDummy2()(q0, q1), ) expected = cirq.Circuit( cirq.X(q0), cirq.Y(q0)**0.5, cirq.CZ(q0, q1), cirq.X(q1), cirq.Y(q1)**0.5, ) c_new = cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset()) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( c_new, expected, atol=1e-6) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( c_new, circuit, atol=1e-6)
def _build_compilation_target_gatesets( gateset: cirq.Gateset, ) -> Sequence[cirq.CompilationTargetGateset]: """Detects compilation target gatesets based on what gates are inside the gateset. If a device contains gates which yield multiple compilation target gatesets, the user can only choose one target gateset to compile to. For example, a device may contain both SYC and SQRT_ISWAP gates which yield two separate target gatesets, but a circuit can only be compiled to either SYC or SQRT_ISWAP for its two-qubit gates, not both. TODO(#5050) when cirq-google CompilationTargetGateset subclasses are implemented, mention that gates which are part of the gateset but not the compilation target gateset are untouched when compiled. """ # TODO(#5050) Subclass core CompilationTargetGatesets in cirq-google. target_gatesets: List[cirq.CompilationTargetGateset] = [] if cirq.CZ in gateset: target_gatesets.append(cirq.CZTargetGateset()) if ops.SYC in gateset: target_gatesets.append(transformers.SycamoreTargetGateset()) if cirq.SQRT_ISWAP in gateset: target_gatesets.append( cirq.SqrtIswapTargetGateset( use_sqrt_iswap_inv=cirq.SQRT_ISWAP_INV in gateset)) return tuple(target_gatesets)
def test_avoids_decompose_when_matrix_available(): class OtherXX(cirq.testing.TwoQubitGate): # coverage: ignore def _has_unitary_(self) -> bool: return True def _unitary_(self) -> np.ndarray: m = np.array([[0, 1], [1, 0]]) return np.kron(m, m) def _decompose_(self, qubits): assert False class OtherOtherXX(cirq.testing.TwoQubitGate): # coverage: ignore def _has_unitary_(self) -> bool: return True def _unitary_(self) -> np.ndarray: m = np.array([[0, 1], [1, 0]]) return np.kron(m, m) def _decompose_(self, qubits): assert False a, b = cirq.LineQubit.range(2) c = cirq.Circuit(OtherXX()(a, b), OtherOtherXX()(a, b)) c = cirq.optimize_for_target_gateset(c, gateset=cirq.CZTargetGateset()) assert len(c) == 0
def test_optimizes_tagged_partial_cz(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit((cirq.CZ**0.5)(a, b).with_tags('mytag')) assert_optimization_not_broken(c) c = cirq.optimize_for_target_gateset(c, gateset=cirq.CZTargetGateset()) assert (len([ 1 for op in c.all_operations() if len(op.qubits) == 2 ]) == 2), 'It should take 2 CZ gates to decompose a CZ**0.5 gate'
def test_optimizes_single_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.ISWAP(a, b)) assert_optimization_not_broken(c) c = cirq.optimize_for_target_gateset(c, gateset=cirq.CZTargetGateset(), ignore_failures=False) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
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 decompose_operation(self, operation: cirq.Operation) -> cirq.OP_TREE: if operation.gate is not None and self.is_supported_gate( operation.gate): return operation return [ cirq.optimize_for_target_gateset( cirq.Circuit(operation), gateset=cirq.CZTargetGateset( allow_partial_czs=True)).all_operations() ]
def test_decompose_partial_czs(circuit): circuit = cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset()) cz_gates = [ op.gate for op in circuit.all_operations() if isinstance(op, cirq.GateOperation) and isinstance(op.gate, cirq.CZPowGate) ] num_full_cz = sum(1 for cz in cz_gates if cz.exponent % 2 == 1) num_part_cz = sum(1 for cz in cz_gates if cz.exponent % 2 != 1) assert num_full_cz == 2 assert num_part_cz == 0
def test_not_decompose_partial_czs(): circuit = cirq.Circuit( cirq.CZPowGate(exponent=0.1, global_shift=-0.5)(*cirq.LineQubit.range(2)), ) cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset()) cz_gates = [ op.gate for op in circuit.all_operations() if isinstance(op, cirq.GateOperation) and isinstance(op.gate, cirq.CZPowGate) ] num_full_cz = sum(1 for cz in cz_gates if cz.exponent % 2 == 1) num_part_cz = sum(1 for cz in cz_gates if cz.exponent % 2 != 1) assert num_full_cz == 0 assert num_part_cz == 1
def rt_config(request): if request.param == 'minimal': return cg.QuantumRuntimeConfiguration( processor_record=cg.SimulatedProcessorWithLocalDeviceRecord('rainbow') ) elif request.param == 'full': return cg.QuantumRuntimeConfiguration( processor_record=cg.SimulatedProcessorWithLocalDeviceRecord('rainbow'), run_id='unit-test', random_seed=52, qubit_placer=cg.RandomDevicePlacer(), target_gateset=cirq.CZTargetGateset(), ) raise ValueError(f"Unknown flavor {request}") # coverage: ignore
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_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 _create_device_spec_with_horizontal_couplings(): # Qubit layout: # x -- x # x -- x # x -- x # x -- x # x -- x grid_qubits = [ cirq.GridQubit(i, j) for i in range(GRID_HEIGHT) for j in range(2) ] spec = v2.device_pb2.DeviceSpecification() spec.valid_qubits.extend([v2.qubit_to_proto_id(q) for q in grid_qubits]) qubit_pairs = [] grid_targets = spec.valid_targets.add() grid_targets.name = '2_qubit_targets' grid_targets.target_ordering = v2.device_pb2.TargetSet.SYMMETRIC for row in range(int(GRID_HEIGHT / 2)): qubit_pairs.append((cirq.GridQubit(row, 0), cirq.GridQubit(row, 1))) for row in range(int(GRID_HEIGHT / 2), GRID_HEIGHT): # Flip the qubit pair order for the second half of qubits # to verify GridDevice properly handles pair symmetry. qubit_pairs.append((cirq.GridQubit(row, 1), cirq.GridQubit(row, 0))) for pair in qubit_pairs: new_target = grid_targets.targets.add() new_target.ids.extend([v2.qubit_to_proto_id(q) for q in pair]) gate_names = [ 'syc', 'sqrt_iswap', 'sqrt_iswap_inv', 'cz', 'phased_xz', 'virtual_zpow', 'physical_zpow', 'coupler_pulse', 'meas', 'wait', ] gate_durations = [(n, i * 1000) for i, n in enumerate(gate_names)] for gate_name, duration in sorted(gate_durations): gate = spec.valid_gates.add() getattr(gate, gate_name).SetInParent() gate.gate_duration_picos = duration expected_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, ) base_duration = cirq.Duration(picos=1_000) expected_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, } expected_target_gatesets = ( cirq.CZTargetGateset(), cirq_google.SycamoreTargetGateset(), cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True), ) return ( _DeviceInfo( grid_qubits, qubit_pairs, expected_gateset, expected_gate_durations, expected_target_gatesets, ), spec, )
] _OPTIMIZER_TYPES = { 'xmon': _get_xmon_optimizers, 'xmon_partial_cz': _get_xmon_optimizers_part_cz, } _TARGET_GATESETS = { 'sqrt_iswap': lambda atol, _: cirq.SqrtIswapTargetGateset(atol=atol), 'sycamore': lambda atol, tabulation: sycamore_gateset.SycamoreTargetGateset( atol=atol, tabulation=tabulation), 'xmon': lambda atol, _: cirq.CZTargetGateset(atol=atol), 'xmon_partial_cz': lambda atol, _: cirq.CZTargetGateset(atol=atol, allow_partial_czs=True), } @lru_cache() def _gate_product_tabulation_cached( optimizer_type: str, tabulation_resolution: float) -> cirq.TwoQubitGateTabulation: random_state = np.random.RandomState(51) if optimizer_type == 'sycamore': return cirq.two_qubit_gate_product_tabulation( cirq.unitary(cg_ops.SYC), tabulation_resolution, random_state=random_state)
pass q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit(UnsupportedDummy()(q0, q1)) assert circuit == cirq.optimize_for_target_gateset( circuit, gateset=cirq.CZTargetGateset()) with pytest.raises(ValueError, match='Unable to convert'): _ = cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset(), ignore_failures=False) @pytest.mark.parametrize( 'gateset', [ cirq.CZTargetGateset(), cirq.CZTargetGateset( atol=1e-6, allow_partial_czs=True, additional_gates=[ cirq.SQRT_ISWAP, cirq.XPowGate, cirq.YPowGate, cirq.GateFamily(cirq.ZPowGate, tags_to_accept=['test_tag']), ], ), cirq.CZTargetGateset(additional_gates=()), ], ) def test_repr(gateset): cirq.testing.assert_equivalent_repr(gateset)
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit): cirq.testing.assert_same_circuits( cirq.optimize_for_target_gateset(before, gateset=cirq.CZTargetGateset()), expected)
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, cirq.CZ, cirq.SQRT_ISWAP) 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), cirq.GateFamily(cirq.SQRT_ISWAP): cirq.Duration(nanos=5), } 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), cirq.GateFamily(cirq.CZ): cirq.Duration(nanos=14), cirq.GateFamily(cirq.SQRT_ISWAP): cirq.Duration(nanos=15), } isolated_qubits = [cirq.GridQubit(9, 9)] target_gatesets = [cirq.CZTargetGateset(), cirq.SqrtIswapTargetGateset()] 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) metadata7 = cirq.GridDeviceMetadata( qubit_pairs, gateset, compilation_target_gatesets=target_gatesets) metadata8 = cirq.GridDeviceMetadata( qubit_pairs, gateset, compilation_target_gatesets=target_gatesets[::-1]) metadata9 = cirq.GridDeviceMetadata( qubit_pairs, gateset, compilation_target_gatesets=tuple(target_gatesets)) metadata10 = cirq.GridDeviceMetadata( qubit_pairs, gateset, compilation_target_gatesets=set(target_gatesets)) 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) eq.add_equality_group(metadata7, metadata8, metadata9, metadata10) assert metadata == metadata5