We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update cirq.google.Bristlecone/Foxtail with accurate duration numbers


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cirq/google/devices/known_devices.py`
Content:
```
1 # Copyright 2018 The Cirq Developers
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     https://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from typing import (Any, Collection, Dict, Optional, Iterable, List, Set, Tuple,
16                     TYPE_CHECKING)
17 
18 from cirq._doc import document
19 from cirq.devices import GridQubit
20 from cirq.google import gate_sets, serializable_gate_set
21 from cirq.google.api import v2
22 from cirq.google.api.v2 import device_pb2
23 from cirq.google.devices.serializable_device import SerializableDevice
24 from cirq.google.devices.xmon_device import XmonDevice
25 from cirq.ops import MeasurementGate, SingleQubitGate, WaitGate
26 from cirq.value import Duration
27 
28 if TYPE_CHECKING:
29     import cirq
30 
31 _2_QUBIT_TARGET_SET = "2_qubit_targets"
32 _MEAS_TARGET_SET = "meas_targets"
33 
34 
35 def _parse_device(s: str) -> Tuple[List[GridQubit], Dict[str, Set[GridQubit]]]:
36     """Parse ASCIIart device layout into info about qubits and connectivity.
37 
38     Args:
39         s: String representing the qubit layout. Each line represents a row,
40             and each character in the row is a qubit, or a blank site if the
41             character is a hyphen '-'. Different letters for the qubit specify
42             which measurement line that qubit is connected to, e.g. all 'A'
43             qubits share a measurement line. Leading and trailing spaces on
44             each line are ignored.
45 
46     Returns:
47         A list of qubits and a dict mapping measurement line name to the qubits
48         on that measurement line.
49     """
50     lines = s.strip().split('\n')
51     qubits = []  # type: List[GridQubit]
52     measurement_lines = {}  # type: Dict[str, Set[GridQubit]]
53     for row, line in enumerate(lines):
54         for col, c in enumerate(line.strip()):
55             if c != '-':
56                 qubit = GridQubit(row, col)
57                 qubits.append(qubit)
58                 measurement_line = measurement_lines.setdefault(c, set())
59                 measurement_line.add(qubit)
60     return qubits, measurement_lines
61 
62 
63 def create_device_proto_from_diagram(
64         ascii_grid: str,
65         gate_sets: Optional[Iterable[
66             serializable_gate_set.SerializableGateSet]] = None,
67         durations_picos: Optional[Dict[str, int]] = None,
68         out: Optional[device_pb2.DeviceSpecification] = None,
69 ) -> device_pb2.DeviceSpecification:
70     """Parse ASCIIart device layout into DeviceSpecification proto.
71 
72     This function assumes that all pairs of adjacent qubits are valid targets
73     for two-qubit gates.
74 
75     Args:
76         ascii_grid: ASCII version of the grid (see _parse_device for details).
77         gate_sets: Gate sets that define the translation between gate ids and
78             cirq Gate objects.
79         durations_picos: A map from gate ids to gate durations in picoseconds.
80         out: If given, populate this proto, otherwise create a new proto.
81     """
82     qubits, _ = _parse_device(ascii_grid)
83 
84     # Create a list of all adjacent pairs on the grid for two-qubit gates.
85     qubit_set = frozenset(qubits)
86     pairs: List[Tuple['cirq.Qid', 'cirq.Qid']] = []
87     for qubit in qubits:
88         for neighbor in sorted(qubit.neighbors()):
89             if neighbor > qubit and neighbor in qubit_set:
90                 pairs.append((qubit, neighbor))
91 
92     return create_device_proto_for_qubits(qubits, pairs, gate_sets,
93                                           durations_picos, out)
94 
95 
96 def create_device_proto_for_qubits(
97         qubits: Collection['cirq.Qid'],
98         pairs: Collection[Tuple['cirq.Qid', 'cirq.Qid']],
99         gate_sets: Optional[Iterable[
100             serializable_gate_set.SerializableGateSet]] = None,
101         durations_picos: Optional[Dict[str, int]] = None,
102         out: Optional[device_pb2.DeviceSpecification] = None,
103 ) -> device_pb2.DeviceSpecification:
104     """Create device spec for the given qubits and coupled pairs.
105 
106     Args:
107         qubits: Qubits that can perform single-qubit gates.
108         pairs: Pairs of coupled qubits that can perform two-qubit gates.
109         gate_sets: Gate sets that define the translation between gate ids and
110             cirq Gate objects.
111         durations_picos: A map from gate ids to gate durations in picoseconds.
112         out: If given, populate this proto, otherwise create a new proto.
113     """
114     if out is None:
115         out = device_pb2.DeviceSpecification()
116 
117     # Create valid qubit list
118     out.valid_qubits.extend(v2.qubit_to_proto_id(q) for q in qubits)
119 
120     # Set up a target set for measurement (any qubit permutation)
121     meas_targets = out.valid_targets.add()
122     meas_targets.name = _MEAS_TARGET_SET
123     meas_targets.target_ordering = device_pb2.TargetSet.SUBSET_PERMUTATION
124 
125     # Set up a target set for 2 qubit gates (specified qubit pairs)
126     grid_targets = out.valid_targets.add()
127     grid_targets.name = _2_QUBIT_TARGET_SET
128     grid_targets.target_ordering = device_pb2.TargetSet.SYMMETRIC
129     for pair in pairs:
130         new_target = grid_targets.targets.add()
131         new_target.ids.extend(v2.qubit_to_proto_id(q) for q in pair)
132 
133     # Create gate sets
134     arg_def = device_pb2.ArgDefinition
135     for gate_set in gate_sets or []:
136         gs_proto = out.valid_gate_sets.add()
137         gs_proto.name = gate_set.gate_set_name
138         gate_ids: Set[str] = set()
139         for gate_type in gate_set.serializers:
140             for serializer in gate_set.serializers[gate_type]:
141                 gate_id = serializer.serialized_gate_id
142                 if gate_id in gate_ids:
143                     # Only add each type once
144                     continue
145 
146                 gate_ids.add(gate_id)
147                 gate = gs_proto.valid_gates.add()
148                 gate.id = gate_id
149 
150                 # Choose target set and number of qubits based on gate type.
151 
152                 # Note: if it is not a measurement gate and doesn't inherit
153                 # from SingleQubitGate, it's assumed to be a two qubit gate.
154                 if gate_type == MeasurementGate:
155                     gate.valid_targets.append(_MEAS_TARGET_SET)
156                 elif gate_type == WaitGate:
157                     # TODO(#2537): Refactor gate-sets / device to eliminate
158                     # The need for checking type here.
159                     gate.number_of_qubits = 1
160                 elif issubclass(gate_type, SingleQubitGate):
161                     gate.number_of_qubits = 1
162                 else:
163                     # This must be a two-qubit gate
164                     gate.valid_targets.append(_2_QUBIT_TARGET_SET)
165                     gate.number_of_qubits = 2
166 
167                 # Add gate duration
168                 if (durations_picos is not None and gate.id in durations_picos):
169                     gate.gate_duration_picos = durations_picos[gate.id]
170 
171                 # Add argument names and types for each gate.
172                 for arg in serializer.args:
173                     new_arg = gate.valid_args.add()
174                     if arg.serialized_type == str:
175                         new_arg.type = arg_def.STRING
176                     if arg.serialized_type == float:
177                         new_arg.type = arg_def.FLOAT
178                     if arg.serialized_type == List[bool]:
179                         new_arg.type = arg_def.REPEATED_BOOLEAN
180                     new_arg.name = arg.serialized_name
181                     # Note: this does not yet support adding allowed_ranges
182 
183     return out
184 
185 
186 _FOXTAIL_GRID = """
187 AAAAABBBBBB
188 CCCCCCDDDDD
189 """
190 
191 
192 class _NamedConstantXmonDevice(XmonDevice):
193 
194     def __init__(self, constant: str, **kwargs) -> None:
195         super().__init__(**kwargs)
196         self._repr = constant
197 
198     def __repr__(self) -> str:
199         return self._repr
200 
201     @classmethod
202     def _from_json_dict_(cls, constant: str, **kwargs):
203         if constant == Foxtail._repr:
204             return Foxtail
205         if constant == Bristlecone._repr:
206             return Bristlecone
207         raise ValueError(f'Unrecognized xmon device name: {constant!r}')
208 
209     def _json_dict_(self) -> Dict[str, Any]:
210         return {
211             'cirq_type': self.__class__.__name__,
212             'constant': self._repr,
213         }
214 
215 
216 Foxtail = _NamedConstantXmonDevice('cirq.google.Foxtail',
217                                    measurement_duration=Duration(nanos=4000),
218                                    exp_w_duration=Duration(nanos=20),
219                                    exp_11_duration=Duration(nanos=50),
220                                    qubits=_parse_device(_FOXTAIL_GRID)[0])
221 document(Foxtail, f"""72 xmon qubit device.
222 
223 **Qubit grid**:
224 ```
225 {str(Foxtail)}
226 ```
227 """)
228 
229 # Duration dict in picoseconds
230 _DURATIONS_FOR_XMON = {
231     'cz': 50_000,
232     'xy': 20_000,
233     'z': 0,
234     'meas': 4_000_000,  # 1000ns for readout, 3000ns for "ring down"
235 }
236 
237 FOXTAIL_PROTO = create_device_proto_from_diagram(_FOXTAIL_GRID,
238                                                  [gate_sets.XMON],
239                                                  _DURATIONS_FOR_XMON)
240 
241 _BRISTLECONE_GRID = """
242 -----AB-----
243 ----ABCD----
244 ---ABCDEF---
245 --ABCDEFGH--
246 -ABCDEFGHIJ-
247 ABCDEFGHIJKL
248 -CDEFGHIJKL-
249 --EFGHIJKL--
250 ---GHIJKL---
251 ----IJKL----
252 -----KL-----
253 """
254 
255 Bristlecone = _NamedConstantXmonDevice(
256     'cirq.google.Bristlecone',
257     measurement_duration=Duration(nanos=4000),
258     exp_w_duration=Duration(nanos=20),
259     exp_11_duration=Duration(nanos=50),
260     qubits=_parse_device(_BRISTLECONE_GRID)[0])
261 document(
262     Bristlecone, f"""72 xmon qubit device.
263 
264 **Qubit grid**:
265 ```
266 {str(Bristlecone)}
267 ```
268 """)
269 
270 BRISTLECONE_PROTO = create_device_proto_from_diagram(_BRISTLECONE_GRID,
271                                                      [gate_sets.XMON],
272                                                      _DURATIONS_FOR_XMON)
273 
274 _SYCAMORE_GRID = """
275 -----AB---
276 ----ABCD--
277 ---ABCDEF-
278 --ABCDEFGH
279 -ABCDEFGHI
280 ABCDEFGHI-
281 -CDEFGHI--
282 --EFGHI---
283 ---GHI----
284 ----I-----
285 """
286 
287 _SYCAMORE_DURATIONS_PICOS = {
288     'xy': 25_000,
289     'xy_half_pi': 25_000,
290     'xy_pi': 25_000,
291     'xyz': 25_000,
292     'fsim_pi_4': 32_000,
293     'inv_fsim_pi_4': 32_000,
294     'syc': 12_000,
295     'z': 0,
296     'meas': 4_000_000,  # 1000 ns for readout, 3000ns for ring_down
297 }
298 
299 SYCAMORE_PROTO = create_device_proto_from_diagram(
300     _SYCAMORE_GRID,
301     [gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET],
302     _SYCAMORE_DURATIONS_PICOS,
303 )
304 
305 Sycamore = SerializableDevice.from_proto(
306     proto=SYCAMORE_PROTO,
307     gate_sets=[gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET])
308 
309 # Subset of the Sycamore grid with a reduced layout.
310 _SYCAMORE23_GRID = """
311 ----------
312 ----------
313 ----------
314 --A-------
315 -ABC------
316 ABCDE-----
317 -CDEFG----
318 --EFGHI---
319 ---GHI----
320 ----I-----
321 """
322 
323 SYCAMORE23_PROTO = create_device_proto_from_diagram(
324     _SYCAMORE23_GRID,
325     [gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET],
326     _SYCAMORE_DURATIONS_PICOS,
327 )
328 
329 Sycamore23 = SerializableDevice.from_proto(
330     proto=SYCAMORE23_PROTO,
331     gate_sets=[gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET])
332
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cirq/google/devices/known_devices.py b/cirq/google/devices/known_devices.py
--- a/cirq/google/devices/known_devices.py
+++ b/cirq/google/devices/known_devices.py
@@ -228,8 +228,8 @@
 
 # Duration dict in picoseconds
 _DURATIONS_FOR_XMON = {
-    'cz': 50_000,
-    'xy': 20_000,
+    'cz': 45_000,
+    'xy': 15_000,
     'z': 0,
     'meas': 4_000_000,  # 1000ns for readout, 3000ns for "ring down"
 }

{"golden_diff": "diff --git a/cirq/google/devices/known_devices.py b/cirq/google/devices/known_devices.py\n--- a/cirq/google/devices/known_devices.py\n+++ b/cirq/google/devices/known_devices.py\n@@ -228,8 +228,8 @@\n \n # Duration dict in picoseconds\n _DURATIONS_FOR_XMON = {\n-    'cz': 50_000,\n-    'xy': 20_000,\n+    'cz': 45_000,\n+    'xy': 15_000,\n     'z': 0,\n     'meas': 4_000_000,  # 1000ns for readout, 3000ns for \"ring down\"\n }\n", "issue": "Update cirq.google.Bristlecone/Foxtail with accurate duration numbers\n\n", "before_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import (Any, Collection, Dict, Optional, Iterable, List, Set, Tuple,\n                    TYPE_CHECKING)\n\nfrom cirq._doc import document\nfrom cirq.devices import GridQubit\nfrom cirq.google import gate_sets, serializable_gate_set\nfrom cirq.google.api import v2\nfrom cirq.google.api.v2 import device_pb2\nfrom cirq.google.devices.serializable_device import SerializableDevice\nfrom cirq.google.devices.xmon_device import XmonDevice\nfrom cirq.ops import MeasurementGate, SingleQubitGate, WaitGate\nfrom cirq.value import Duration\n\nif TYPE_CHECKING:\n    import cirq\n\n_2_QUBIT_TARGET_SET = \"2_qubit_targets\"\n_MEAS_TARGET_SET = \"meas_targets\"\n\n\ndef _parse_device(s: str) -> Tuple[List[GridQubit], Dict[str, Set[GridQubit]]]:\n    \"\"\"Parse ASCIIart device layout into info about qubits and connectivity.\n\n    Args:\n        s: String representing the qubit layout. Each line represents a row,\n            and each character in the row is a qubit, or a blank site if the\n            character is a hyphen '-'. Different letters for the qubit specify\n            which measurement line that qubit is connected to, e.g. all 'A'\n            qubits share a measurement line. Leading and trailing spaces on\n            each line are ignored.\n\n    Returns:\n        A list of qubits and a dict mapping measurement line name to the qubits\n        on that measurement line.\n    \"\"\"\n    lines = s.strip().split('\\n')\n    qubits = []  # type: List[GridQubit]\n    measurement_lines = {}  # type: Dict[str, Set[GridQubit]]\n    for row, line in enumerate(lines):\n        for col, c in enumerate(line.strip()):\n            if c != '-':\n                qubit = GridQubit(row, col)\n                qubits.append(qubit)\n                measurement_line = measurement_lines.setdefault(c, set())\n                measurement_line.add(qubit)\n    return qubits, measurement_lines\n\n\ndef create_device_proto_from_diagram(\n        ascii_grid: str,\n        gate_sets: Optional[Iterable[\n            serializable_gate_set.SerializableGateSet]] = None,\n        durations_picos: Optional[Dict[str, int]] = None,\n        out: Optional[device_pb2.DeviceSpecification] = None,\n) -> device_pb2.DeviceSpecification:\n    \"\"\"Parse ASCIIart device layout into DeviceSpecification proto.\n\n    This function assumes that all pairs of adjacent qubits are valid targets\n    for two-qubit gates.\n\n    Args:\n        ascii_grid: ASCII version of the grid (see _parse_device for details).\n        gate_sets: Gate sets that define the translation between gate ids and\n            cirq Gate objects.\n        durations_picos: A map from gate ids to gate durations in picoseconds.\n        out: If given, populate this proto, otherwise create a new proto.\n    \"\"\"\n    qubits, _ = _parse_device(ascii_grid)\n\n    # Create a list of all adjacent pairs on the grid for two-qubit gates.\n    qubit_set = frozenset(qubits)\n    pairs: List[Tuple['cirq.Qid', 'cirq.Qid']] = []\n    for qubit in qubits:\n        for neighbor in sorted(qubit.neighbors()):\n            if neighbor > qubit and neighbor in qubit_set:\n                pairs.append((qubit, neighbor))\n\n    return create_device_proto_for_qubits(qubits, pairs, gate_sets,\n                                          durations_picos, out)\n\n\ndef create_device_proto_for_qubits(\n        qubits: Collection['cirq.Qid'],\n        pairs: Collection[Tuple['cirq.Qid', 'cirq.Qid']],\n        gate_sets: Optional[Iterable[\n            serializable_gate_set.SerializableGateSet]] = None,\n        durations_picos: Optional[Dict[str, int]] = None,\n        out: Optional[device_pb2.DeviceSpecification] = None,\n) -> device_pb2.DeviceSpecification:\n    \"\"\"Create device spec for the given qubits and coupled pairs.\n\n    Args:\n        qubits: Qubits that can perform single-qubit gates.\n        pairs: Pairs of coupled qubits that can perform two-qubit gates.\n        gate_sets: Gate sets that define the translation between gate ids and\n            cirq Gate objects.\n        durations_picos: A map from gate ids to gate durations in picoseconds.\n        out: If given, populate this proto, otherwise create a new proto.\n    \"\"\"\n    if out is None:\n        out = device_pb2.DeviceSpecification()\n\n    # Create valid qubit list\n    out.valid_qubits.extend(v2.qubit_to_proto_id(q) for q in qubits)\n\n    # Set up a target set for measurement (any qubit permutation)\n    meas_targets = out.valid_targets.add()\n    meas_targets.name = _MEAS_TARGET_SET\n    meas_targets.target_ordering = device_pb2.TargetSet.SUBSET_PERMUTATION\n\n    # Set up a target set for 2 qubit gates (specified qubit pairs)\n    grid_targets = out.valid_targets.add()\n    grid_targets.name = _2_QUBIT_TARGET_SET\n    grid_targets.target_ordering = device_pb2.TargetSet.SYMMETRIC\n    for pair in pairs:\n        new_target = grid_targets.targets.add()\n        new_target.ids.extend(v2.qubit_to_proto_id(q) for q in pair)\n\n    # Create gate sets\n    arg_def = device_pb2.ArgDefinition\n    for gate_set in gate_sets or []:\n        gs_proto = out.valid_gate_sets.add()\n        gs_proto.name = gate_set.gate_set_name\n        gate_ids: Set[str] = set()\n        for gate_type in gate_set.serializers:\n            for serializer in gate_set.serializers[gate_type]:\n                gate_id = serializer.serialized_gate_id\n                if gate_id in gate_ids:\n                    # Only add each type once\n                    continue\n\n                gate_ids.add(gate_id)\n                gate = gs_proto.valid_gates.add()\n                gate.id = gate_id\n\n                # Choose target set and number of qubits based on gate type.\n\n                # Note: if it is not a measurement gate and doesn't inherit\n                # from SingleQubitGate, it's assumed to be a two qubit gate.\n                if gate_type == MeasurementGate:\n                    gate.valid_targets.append(_MEAS_TARGET_SET)\n                elif gate_type == WaitGate:\n                    # TODO(#2537): Refactor gate-sets / device to eliminate\n                    # The need for checking type here.\n                    gate.number_of_qubits = 1\n                elif issubclass(gate_type, SingleQubitGate):\n                    gate.number_of_qubits = 1\n                else:\n                    # This must be a two-qubit gate\n                    gate.valid_targets.append(_2_QUBIT_TARGET_SET)\n                    gate.number_of_qubits = 2\n\n                # Add gate duration\n                if (durations_picos is not None and gate.id in durations_picos):\n                    gate.gate_duration_picos = durations_picos[gate.id]\n\n                # Add argument names and types for each gate.\n                for arg in serializer.args:\n                    new_arg = gate.valid_args.add()\n                    if arg.serialized_type == str:\n                        new_arg.type = arg_def.STRING\n                    if arg.serialized_type == float:\n                        new_arg.type = arg_def.FLOAT\n                    if arg.serialized_type == List[bool]:\n                        new_arg.type = arg_def.REPEATED_BOOLEAN\n                    new_arg.name = arg.serialized_name\n                    # Note: this does not yet support adding allowed_ranges\n\n    return out\n\n\n_FOXTAIL_GRID = \"\"\"\nAAAAABBBBBB\nCCCCCCDDDDD\n\"\"\"\n\n\nclass _NamedConstantXmonDevice(XmonDevice):\n\n    def __init__(self, constant: str, **kwargs) -> None:\n        super().__init__(**kwargs)\n        self._repr = constant\n\n    def __repr__(self) -> str:\n        return self._repr\n\n    @classmethod\n    def _from_json_dict_(cls, constant: str, **kwargs):\n        if constant == Foxtail._repr:\n            return Foxtail\n        if constant == Bristlecone._repr:\n            return Bristlecone\n        raise ValueError(f'Unrecognized xmon device name: {constant!r}')\n\n    def _json_dict_(self) -> Dict[str, Any]:\n        return {\n            'cirq_type': self.__class__.__name__,\n            'constant': self._repr,\n        }\n\n\nFoxtail = _NamedConstantXmonDevice('cirq.google.Foxtail',\n                                   measurement_duration=Duration(nanos=4000),\n                                   exp_w_duration=Duration(nanos=20),\n                                   exp_11_duration=Duration(nanos=50),\n                                   qubits=_parse_device(_FOXTAIL_GRID)[0])\ndocument(Foxtail, f\"\"\"72 xmon qubit device.\n\n**Qubit grid**:\n```\n{str(Foxtail)}\n```\n\"\"\")\n\n# Duration dict in picoseconds\n_DURATIONS_FOR_XMON = {\n    'cz': 50_000,\n    'xy': 20_000,\n    'z': 0,\n    'meas': 4_000_000,  # 1000ns for readout, 3000ns for \"ring down\"\n}\n\nFOXTAIL_PROTO = create_device_proto_from_diagram(_FOXTAIL_GRID,\n                                                 [gate_sets.XMON],\n                                                 _DURATIONS_FOR_XMON)\n\n_BRISTLECONE_GRID = \"\"\"\n-----AB-----\n----ABCD----\n---ABCDEF---\n--ABCDEFGH--\n-ABCDEFGHIJ-\nABCDEFGHIJKL\n-CDEFGHIJKL-\n--EFGHIJKL--\n---GHIJKL---\n----IJKL----\n-----KL-----\n\"\"\"\n\nBristlecone = _NamedConstantXmonDevice(\n    'cirq.google.Bristlecone',\n    measurement_duration=Duration(nanos=4000),\n    exp_w_duration=Duration(nanos=20),\n    exp_11_duration=Duration(nanos=50),\n    qubits=_parse_device(_BRISTLECONE_GRID)[0])\ndocument(\n    Bristlecone, f\"\"\"72 xmon qubit device.\n\n**Qubit grid**:\n```\n{str(Bristlecone)}\n```\n\"\"\")\n\nBRISTLECONE_PROTO = create_device_proto_from_diagram(_BRISTLECONE_GRID,\n                                                     [gate_sets.XMON],\n                                                     _DURATIONS_FOR_XMON)\n\n_SYCAMORE_GRID = \"\"\"\n-----AB---\n----ABCD--\n---ABCDEF-\n--ABCDEFGH\n-ABCDEFGHI\nABCDEFGHI-\n-CDEFGHI--\n--EFGHI---\n---GHI----\n----I-----\n\"\"\"\n\n_SYCAMORE_DURATIONS_PICOS = {\n    'xy': 25_000,\n    'xy_half_pi': 25_000,\n    'xy_pi': 25_000,\n    'xyz': 25_000,\n    'fsim_pi_4': 32_000,\n    'inv_fsim_pi_4': 32_000,\n    'syc': 12_000,\n    'z': 0,\n    'meas': 4_000_000,  # 1000 ns for readout, 3000ns for ring_down\n}\n\nSYCAMORE_PROTO = create_device_proto_from_diagram(\n    _SYCAMORE_GRID,\n    [gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET],\n    _SYCAMORE_DURATIONS_PICOS,\n)\n\nSycamore = SerializableDevice.from_proto(\n    proto=SYCAMORE_PROTO,\n    gate_sets=[gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET])\n\n# Subset of the Sycamore grid with a reduced layout.\n_SYCAMORE23_GRID = \"\"\"\n----------\n----------\n----------\n--A-------\n-ABC------\nABCDE-----\n-CDEFG----\n--EFGHI---\n---GHI----\n----I-----\n\"\"\"\n\nSYCAMORE23_PROTO = create_device_proto_from_diagram(\n    _SYCAMORE23_GRID,\n    [gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET],\n    _SYCAMORE_DURATIONS_PICOS,\n)\n\nSycamore23 = SerializableDevice.from_proto(\n    proto=SYCAMORE23_PROTO,\n    gate_sets=[gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET])\n", "path": "cirq/google/devices/known_devices.py"}], "after_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import (Any, Collection, Dict, Optional, Iterable, List, Set, Tuple,\n                    TYPE_CHECKING)\n\nfrom cirq._doc import document\nfrom cirq.devices import GridQubit\nfrom cirq.google import gate_sets, serializable_gate_set\nfrom cirq.google.api import v2\nfrom cirq.google.api.v2 import device_pb2\nfrom cirq.google.devices.serializable_device import SerializableDevice\nfrom cirq.google.devices.xmon_device import XmonDevice\nfrom cirq.ops import MeasurementGate, SingleQubitGate, WaitGate\nfrom cirq.value import Duration\n\nif TYPE_CHECKING:\n    import cirq\n\n_2_QUBIT_TARGET_SET = \"2_qubit_targets\"\n_MEAS_TARGET_SET = \"meas_targets\"\n\n\ndef _parse_device(s: str) -> Tuple[List[GridQubit], Dict[str, Set[GridQubit]]]:\n    \"\"\"Parse ASCIIart device layout into info about qubits and connectivity.\n\n    Args:\n        s: String representing the qubit layout. Each line represents a row,\n            and each character in the row is a qubit, or a blank site if the\n            character is a hyphen '-'. Different letters for the qubit specify\n            which measurement line that qubit is connected to, e.g. all 'A'\n            qubits share a measurement line. Leading and trailing spaces on\n            each line are ignored.\n\n    Returns:\n        A list of qubits and a dict mapping measurement line name to the qubits\n        on that measurement line.\n    \"\"\"\n    lines = s.strip().split('\\n')\n    qubits = []  # type: List[GridQubit]\n    measurement_lines = {}  # type: Dict[str, Set[GridQubit]]\n    for row, line in enumerate(lines):\n        for col, c in enumerate(line.strip()):\n            if c != '-':\n                qubit = GridQubit(row, col)\n                qubits.append(qubit)\n                measurement_line = measurement_lines.setdefault(c, set())\n                measurement_line.add(qubit)\n    return qubits, measurement_lines\n\n\ndef create_device_proto_from_diagram(\n        ascii_grid: str,\n        gate_sets: Optional[Iterable[\n            serializable_gate_set.SerializableGateSet]] = None,\n        durations_picos: Optional[Dict[str, int]] = None,\n        out: Optional[device_pb2.DeviceSpecification] = None,\n) -> device_pb2.DeviceSpecification:\n    \"\"\"Parse ASCIIart device layout into DeviceSpecification proto.\n\n    This function assumes that all pairs of adjacent qubits are valid targets\n    for two-qubit gates.\n\n    Args:\n        ascii_grid: ASCII version of the grid (see _parse_device for details).\n        gate_sets: Gate sets that define the translation between gate ids and\n            cirq Gate objects.\n        durations_picos: A map from gate ids to gate durations in picoseconds.\n        out: If given, populate this proto, otherwise create a new proto.\n    \"\"\"\n    qubits, _ = _parse_device(ascii_grid)\n\n    # Create a list of all adjacent pairs on the grid for two-qubit gates.\n    qubit_set = frozenset(qubits)\n    pairs: List[Tuple['cirq.Qid', 'cirq.Qid']] = []\n    for qubit in qubits:\n        for neighbor in sorted(qubit.neighbors()):\n            if neighbor > qubit and neighbor in qubit_set:\n                pairs.append((qubit, neighbor))\n\n    return create_device_proto_for_qubits(qubits, pairs, gate_sets,\n                                          durations_picos, out)\n\n\ndef create_device_proto_for_qubits(\n        qubits: Collection['cirq.Qid'],\n        pairs: Collection[Tuple['cirq.Qid', 'cirq.Qid']],\n        gate_sets: Optional[Iterable[\n            serializable_gate_set.SerializableGateSet]] = None,\n        durations_picos: Optional[Dict[str, int]] = None,\n        out: Optional[device_pb2.DeviceSpecification] = None,\n) -> device_pb2.DeviceSpecification:\n    \"\"\"Create device spec for the given qubits and coupled pairs.\n\n    Args:\n        qubits: Qubits that can perform single-qubit gates.\n        pairs: Pairs of coupled qubits that can perform two-qubit gates.\n        gate_sets: Gate sets that define the translation between gate ids and\n            cirq Gate objects.\n        durations_picos: A map from gate ids to gate durations in picoseconds.\n        out: If given, populate this proto, otherwise create a new proto.\n    \"\"\"\n    if out is None:\n        out = device_pb2.DeviceSpecification()\n\n    # Create valid qubit list\n    out.valid_qubits.extend(v2.qubit_to_proto_id(q) for q in qubits)\n\n    # Set up a target set for measurement (any qubit permutation)\n    meas_targets = out.valid_targets.add()\n    meas_targets.name = _MEAS_TARGET_SET\n    meas_targets.target_ordering = device_pb2.TargetSet.SUBSET_PERMUTATION\n\n    # Set up a target set for 2 qubit gates (specified qubit pairs)\n    grid_targets = out.valid_targets.add()\n    grid_targets.name = _2_QUBIT_TARGET_SET\n    grid_targets.target_ordering = device_pb2.TargetSet.SYMMETRIC\n    for pair in pairs:\n        new_target = grid_targets.targets.add()\n        new_target.ids.extend(v2.qubit_to_proto_id(q) for q in pair)\n\n    # Create gate sets\n    arg_def = device_pb2.ArgDefinition\n    for gate_set in gate_sets or []:\n        gs_proto = out.valid_gate_sets.add()\n        gs_proto.name = gate_set.gate_set_name\n        gate_ids: Set[str] = set()\n        for gate_type in gate_set.serializers:\n            for serializer in gate_set.serializers[gate_type]:\n                gate_id = serializer.serialized_gate_id\n                if gate_id in gate_ids:\n                    # Only add each type once\n                    continue\n\n                gate_ids.add(gate_id)\n                gate = gs_proto.valid_gates.add()\n                gate.id = gate_id\n\n                # Choose target set and number of qubits based on gate type.\n\n                # Note: if it is not a measurement gate and doesn't inherit\n                # from SingleQubitGate, it's assumed to be a two qubit gate.\n                if gate_type == MeasurementGate:\n                    gate.valid_targets.append(_MEAS_TARGET_SET)\n                elif gate_type == WaitGate:\n                    # TODO(#2537): Refactor gate-sets / device to eliminate\n                    # The need for checking type here.\n                    gate.number_of_qubits = 1\n                elif issubclass(gate_type, SingleQubitGate):\n                    gate.number_of_qubits = 1\n                else:\n                    # This must be a two-qubit gate\n                    gate.valid_targets.append(_2_QUBIT_TARGET_SET)\n                    gate.number_of_qubits = 2\n\n                # Add gate duration\n                if (durations_picos is not None and gate.id in durations_picos):\n                    gate.gate_duration_picos = durations_picos[gate.id]\n\n                # Add argument names and types for each gate.\n                for arg in serializer.args:\n                    new_arg = gate.valid_args.add()\n                    if arg.serialized_type == str:\n                        new_arg.type = arg_def.STRING\n                    if arg.serialized_type == float:\n                        new_arg.type = arg_def.FLOAT\n                    if arg.serialized_type == List[bool]:\n                        new_arg.type = arg_def.REPEATED_BOOLEAN\n                    new_arg.name = arg.serialized_name\n                    # Note: this does not yet support adding allowed_ranges\n\n    return out\n\n\n_FOXTAIL_GRID = \"\"\"\nAAAAABBBBBB\nCCCCCCDDDDD\n\"\"\"\n\n\nclass _NamedConstantXmonDevice(XmonDevice):\n\n    def __init__(self, constant: str, **kwargs) -> None:\n        super().__init__(**kwargs)\n        self._repr = constant\n\n    def __repr__(self) -> str:\n        return self._repr\n\n    @classmethod\n    def _from_json_dict_(cls, constant: str, **kwargs):\n        if constant == Foxtail._repr:\n            return Foxtail\n        if constant == Bristlecone._repr:\n            return Bristlecone\n        raise ValueError(f'Unrecognized xmon device name: {constant!r}')\n\n    def _json_dict_(self) -> Dict[str, Any]:\n        return {\n            'cirq_type': self.__class__.__name__,\n            'constant': self._repr,\n        }\n\n\nFoxtail = _NamedConstantXmonDevice('cirq.google.Foxtail',\n                                   measurement_duration=Duration(nanos=4000),\n                                   exp_w_duration=Duration(nanos=20),\n                                   exp_11_duration=Duration(nanos=50),\n                                   qubits=_parse_device(_FOXTAIL_GRID)[0])\ndocument(Foxtail, f\"\"\"72 xmon qubit device.\n\n**Qubit grid**:\n```\n{str(Foxtail)}\n```\n\"\"\")\n\n# Duration dict in picoseconds\n_DURATIONS_FOR_XMON = {\n    'cz': 45_000,\n    'xy': 15_000,\n    'z': 0,\n    'meas': 4_000_000,  # 1000ns for readout, 3000ns for \"ring down\"\n}\n\nFOXTAIL_PROTO = create_device_proto_from_diagram(_FOXTAIL_GRID,\n                                                 [gate_sets.XMON],\n                                                 _DURATIONS_FOR_XMON)\n\n_BRISTLECONE_GRID = \"\"\"\n-----AB-----\n----ABCD----\n---ABCDEF---\n--ABCDEFGH--\n-ABCDEFGHIJ-\nABCDEFGHIJKL\n-CDEFGHIJKL-\n--EFGHIJKL--\n---GHIJKL---\n----IJKL----\n-----KL-----\n\"\"\"\n\nBristlecone = _NamedConstantXmonDevice(\n    'cirq.google.Bristlecone',\n    measurement_duration=Duration(nanos=4000),\n    exp_w_duration=Duration(nanos=20),\n    exp_11_duration=Duration(nanos=50),\n    qubits=_parse_device(_BRISTLECONE_GRID)[0])\ndocument(\n    Bristlecone, f\"\"\"72 xmon qubit device.\n\n**Qubit grid**:\n```\n{str(Bristlecone)}\n```\n\"\"\")\n\nBRISTLECONE_PROTO = create_device_proto_from_diagram(_BRISTLECONE_GRID,\n                                                     [gate_sets.XMON],\n                                                     _DURATIONS_FOR_XMON)\n\n_SYCAMORE_GRID = \"\"\"\n-----AB---\n----ABCD--\n---ABCDEF-\n--ABCDEFGH\n-ABCDEFGHI\nABCDEFGHI-\n-CDEFGHI--\n--EFGHI---\n---GHI----\n----I-----\n\"\"\"\n\n_SYCAMORE_DURATIONS_PICOS = {\n    'xy': 25_000,\n    'xy_half_pi': 25_000,\n    'xy_pi': 25_000,\n    'xyz': 25_000,\n    'fsim_pi_4': 32_000,\n    'inv_fsim_pi_4': 32_000,\n    'syc': 12_000,\n    'z': 0,\n    'meas': 4_000_000,  # 1000 ns for readout, 3000ns for ring_down\n}\n\nSYCAMORE_PROTO = create_device_proto_from_diagram(\n    _SYCAMORE_GRID,\n    [gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET],\n    _SYCAMORE_DURATIONS_PICOS,\n)\n\nSycamore = SerializableDevice.from_proto(\n    proto=SYCAMORE_PROTO,\n    gate_sets=[gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET])\n\n# Subset of the Sycamore grid with a reduced layout.\n_SYCAMORE23_GRID = \"\"\"\n----------\n----------\n----------\n--A-------\n-ABC------\nABCDE-----\n-CDEFG----\n--EFGHI---\n---GHI----\n----I-----\n\"\"\"\n\nSYCAMORE23_PROTO = create_device_proto_from_diagram(\n    _SYCAMORE23_GRID,\n    [gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET],\n    _SYCAMORE_DURATIONS_PICOS,\n)\n\nSycamore23 = SerializableDevice.from_proto(\n    proto=SYCAMORE23_PROTO,\n    gate_sets=[gate_sets.SQRT_ISWAP_GATESET, gate_sets.SYC_GATESET])\n", "path": "cirq/google/devices/known_devices.py"}]}