def _serialize_gateset_and_gate_durations(
    out: v2.device_pb2.DeviceSpecification,
    gateset: cirq.Gateset,
    gate_durations: Mapping[cirq.GateFamily, cirq.Duration],
) -> v2.device_pb2.DeviceSpecification:
    """Serializes the given gateset and gate durations to DeviceSpecification."""

    gate_specs: dict[str, v2.device_pb2.GateSpecification] = {}
    for gate_family in gateset.gates:
        gate_spec = v2.device_pb2.GateSpecification()
        gate_rep = next(
            (gr for gr in _GATES for gf in gr.supported_gates if gf == gate_family), None
        )
        if gate_rep is None:
            raise ValueError(f'Unrecognized gate: {gate_family}.')
        gate_name = gate_rep.gate_spec_name

        # Set gate
        getattr(gate_spec, gate_name).SetInParent()

        # Set gate duration
        gate_durations_picos = {
            int(gate_durations[gf].total_picos())
            for gf in gate_rep.supported_gates
            if gf in gate_durations
        }
        if len(gate_durations_picos) > 1:
            raise ValueError(
                'Multiple gate families in the following list exist in the gate duration dict, and '
                f'they are expected to have the same duration value: {gate_rep.supported_gates}'
            )
        elif len(gate_durations_picos) == 1:
            gate_spec.gate_duration_picos = gate_durations_picos.pop()

        # GateSpecification dedup. Multiple gates or GateFamilies in the gateset could map to the
        # same GateSpecification.
        gate_specs[gate_name] = gate_spec

    # Sort by gate name to keep valid_gates stable.
    out.valid_gates.extend(v for _, v in sorted(gate_specs.items()))

    return out
Serializes the given gateset and gate durations to DeviceSpecification.
cirq-google/cirq_google/devices/grid_device.py