We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Engine measurements are bytes but simulator measurements are bools
This causes code that works with the simulator to fail when given engine results. We should make these consistent.

Example code that works with simulator results but not engine results:

```python
a = np.zeros([repetition_count], dtype=np.bool)
a ^= results.measurements['x'][:, 0]
a ^= results.measurements['y'][:, 0]
```

--- 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/programs.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 from typing import Dict, Iterable, Sequence, Tuple, TYPE_CHECKING
15 
16 import numpy as np
17 
18 from cirq.api.google.v1 import operations_pb2
19 from cirq.google import xmon_gates, xmon_gate_ext
20 from cirq.google.xmon_device import XmonDevice
21 from cirq.schedules import Schedule, ScheduledOperation
22 from cirq.value import Timestamp
23 
24 if TYPE_CHECKING:
25     from typing import Optional  # pylint: disable=unused-import
26 
27 
28 def schedule_to_proto(schedule: Schedule) -> Iterable[operations_pb2.Operation]:
29     """Convert a schedule into protobufs.
30 
31     Args:
32         schedule: The schedule to convert to protobufs. Must contain only gates
33             that can be cast to xmon gates.
34 
35     Yields:
36         operations_pb2.Operation
37     """
38     last_time_picos = None  # type: Optional[int]
39     for so in schedule.scheduled_operations:
40         gate = xmon_gate_ext.cast(xmon_gates.XmonGate, so.operation.gate)
41         op = gate.to_proto(*so.operation.qubits)
42         time_picos = so.time.raw_picos()
43         if last_time_picos is None:
44             op.incremental_delay_picoseconds = time_picos
45         else:
46             op.incremental_delay_picoseconds = time_picos - last_time_picos
47         last_time_picos = time_picos
48         yield op
49 
50 
51 def schedule_from_proto(
52         device: XmonDevice,
53         ops: Iterable[operations_pb2.Operation],
54 ) -> Schedule:
55     """Convert protobufs into a Schedule for the given device."""
56     scheduled_ops = []
57     last_time_picos = 0
58     for op in ops:
59         time_picos = last_time_picos + op.incremental_delay_picoseconds
60         last_time_picos = time_picos
61         xmon_op = xmon_gates.XmonGate.from_proto(op)
62         scheduled_ops.append(ScheduledOperation.op_at_on(
63             operation=xmon_op,
64             time=Timestamp(picos=time_picos),
65             device=device,
66         ))
67     return Schedule(device, scheduled_ops)
68 
69 
70 def pack_results(measurements: Sequence[Tuple[str, np.ndarray]]) -> bytes:
71     """Pack measurement results into a byte string.
72 
73     Args:
74         measurements: A sequence of tuples, one for each measurement, consisting
75             of a string key and an array of boolean data. The data should be
76             a 2-D array indexed by (repetition, qubit_index). All data for all
77             measurements must have the same number of repetitions.
78 
79     Returns:
80         Packed bytes, as described in the unpack_results docstring below.
81 
82     Raises:
83         ValueError if the measurement data do not have the compatible shapes.
84     """
85     if not measurements:
86         return b''
87 
88     shapes = [(key, np.shape(data)) for key, data in measurements]
89     if not all(len(shape) == 2 for _, shape in shapes):
90         raise ValueError("Expected 2-D data: shapes={}".format(shapes))
91 
92     reps = shapes[0][1][0]
93     if not all(shape[0] == reps for _, shape in shapes):
94         raise ValueError(
95             "Expected same reps for all keys: shapes={}".format(shapes))
96 
97     bits = np.hstack(np.asarray(data, dtype=bool) for _, data in measurements)
98     bits = bits.reshape(-1)
99 
100     # Pad length to multiple of 8 if needed.
101     remainder = len(bits) % 8
102     if remainder:
103         bits = np.pad(bits, (0, 8 - remainder), 'constant')
104 
105     # Pack in little-endian bit order.
106     bits = bits.reshape((-1, 8))[:, ::-1]
107     byte_arr = np.packbits(bits, axis=1).reshape(-1)
108 
109     return byte_arr.tobytes()
110 
111 
112 def unpack_results(
113         data: bytes,
114         repetitions: int,
115         key_sizes: Sequence[Tuple[str, int]]
116 ) -> Dict[str, np.ndarray]:
117     """Unpack data from a bitstring into individual measurement results.
118 
119     Args:
120         data: Packed measurement results, in the form <rep0><rep1>...
121             where each repetition is <key0_0>..<key0_{size0-1}><key1_0>...
122             with bits packed in little-endian order in each byte.
123         repetitions: number of repetitions.
124         key_sizes: Keys and sizes of the measurements in the data.
125 
126     Returns:
127         Dict mapping measurement key to a 2D array of boolean results. Each
128         array has shape (repetitions, size) with size for that measurement.
129     """
130     bits_per_rep = sum(size for _, size in key_sizes)
131     total_bits = repetitions * bits_per_rep
132 
133     byte_arr = np.frombuffer(data, dtype='uint8').reshape((len(data), 1))
134     bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1)
135     bits = bits[:total_bits].reshape((repetitions, bits_per_rep))
136 
137     results = {}
138     ofs = 0
139     for key, size in key_sizes:
140         results[key] = bits[:, ofs:ofs + size]
141         ofs += size
142 
143     return results
144
```
--- 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/programs.py b/cirq/google/programs.py
--- a/cirq/google/programs.py
+++ b/cirq/google/programs.py
@@ -131,7 +131,7 @@
     total_bits = repetitions * bits_per_rep
 
     byte_arr = np.frombuffer(data, dtype='uint8').reshape((len(data), 1))
-    bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1)
+    bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1).astype(bool)
     bits = bits[:total_bits].reshape((repetitions, bits_per_rep))
 
     results = {}

{"golden_diff": "diff --git a/cirq/google/programs.py b/cirq/google/programs.py\n--- a/cirq/google/programs.py\n+++ b/cirq/google/programs.py\n@@ -131,7 +131,7 @@\n     total_bits = repetitions * bits_per_rep\n \n     byte_arr = np.frombuffer(data, dtype='uint8').reshape((len(data), 1))\n-    bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1)\n+    bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1).astype(bool)\n     bits = bits[:total_bits].reshape((repetitions, bits_per_rep))\n \n     results = {}\n", "issue": "Engine measurements are bytes but simulator measurements are bools\nThis causes code that works with the simulator to fail when given engine results. We should make these consistent.\r\n\r\nExample code that works with simulator results but not engine results:\r\n\r\n```python\r\na = np.zeros([repetition_count], dtype=np.bool)\r\na ^= results.measurements['x'][:, 0]\r\na ^= results.measurements['y'][:, 0]\r\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.\nfrom typing import Dict, Iterable, Sequence, Tuple, TYPE_CHECKING\n\nimport numpy as np\n\nfrom cirq.api.google.v1 import operations_pb2\nfrom cirq.google import xmon_gates, xmon_gate_ext\nfrom cirq.google.xmon_device import XmonDevice\nfrom cirq.schedules import Schedule, ScheduledOperation\nfrom cirq.value import Timestamp\n\nif TYPE_CHECKING:\n    from typing import Optional  # pylint: disable=unused-import\n\n\ndef schedule_to_proto(schedule: Schedule) -> Iterable[operations_pb2.Operation]:\n    \"\"\"Convert a schedule into protobufs.\n\n    Args:\n        schedule: The schedule to convert to protobufs. Must contain only gates\n            that can be cast to xmon gates.\n\n    Yields:\n        operations_pb2.Operation\n    \"\"\"\n    last_time_picos = None  # type: Optional[int]\n    for so in schedule.scheduled_operations:\n        gate = xmon_gate_ext.cast(xmon_gates.XmonGate, so.operation.gate)\n        op = gate.to_proto(*so.operation.qubits)\n        time_picos = so.time.raw_picos()\n        if last_time_picos is None:\n            op.incremental_delay_picoseconds = time_picos\n        else:\n            op.incremental_delay_picoseconds = time_picos - last_time_picos\n        last_time_picos = time_picos\n        yield op\n\n\ndef schedule_from_proto(\n        device: XmonDevice,\n        ops: Iterable[operations_pb2.Operation],\n) -> Schedule:\n    \"\"\"Convert protobufs into a Schedule for the given device.\"\"\"\n    scheduled_ops = []\n    last_time_picos = 0\n    for op in ops:\n        time_picos = last_time_picos + op.incremental_delay_picoseconds\n        last_time_picos = time_picos\n        xmon_op = xmon_gates.XmonGate.from_proto(op)\n        scheduled_ops.append(ScheduledOperation.op_at_on(\n            operation=xmon_op,\n            time=Timestamp(picos=time_picos),\n            device=device,\n        ))\n    return Schedule(device, scheduled_ops)\n\n\ndef pack_results(measurements: Sequence[Tuple[str, np.ndarray]]) -> bytes:\n    \"\"\"Pack measurement results into a byte string.\n\n    Args:\n        measurements: A sequence of tuples, one for each measurement, consisting\n            of a string key and an array of boolean data. The data should be\n            a 2-D array indexed by (repetition, qubit_index). All data for all\n            measurements must have the same number of repetitions.\n\n    Returns:\n        Packed bytes, as described in the unpack_results docstring below.\n\n    Raises:\n        ValueError if the measurement data do not have the compatible shapes.\n    \"\"\"\n    if not measurements:\n        return b''\n\n    shapes = [(key, np.shape(data)) for key, data in measurements]\n    if not all(len(shape) == 2 for _, shape in shapes):\n        raise ValueError(\"Expected 2-D data: shapes={}\".format(shapes))\n\n    reps = shapes[0][1][0]\n    if not all(shape[0] == reps for _, shape in shapes):\n        raise ValueError(\n            \"Expected same reps for all keys: shapes={}\".format(shapes))\n\n    bits = np.hstack(np.asarray(data, dtype=bool) for _, data in measurements)\n    bits = bits.reshape(-1)\n\n    # Pad length to multiple of 8 if needed.\n    remainder = len(bits) % 8\n    if remainder:\n        bits = np.pad(bits, (0, 8 - remainder), 'constant')\n\n    # Pack in little-endian bit order.\n    bits = bits.reshape((-1, 8))[:, ::-1]\n    byte_arr = np.packbits(bits, axis=1).reshape(-1)\n\n    return byte_arr.tobytes()\n\n\ndef unpack_results(\n        data: bytes,\n        repetitions: int,\n        key_sizes: Sequence[Tuple[str, int]]\n) -> Dict[str, np.ndarray]:\n    \"\"\"Unpack data from a bitstring into individual measurement results.\n\n    Args:\n        data: Packed measurement results, in the form <rep0><rep1>...\n            where each repetition is <key0_0>..<key0_{size0-1}><key1_0>...\n            with bits packed in little-endian order in each byte.\n        repetitions: number of repetitions.\n        key_sizes: Keys and sizes of the measurements in the data.\n\n    Returns:\n        Dict mapping measurement key to a 2D array of boolean results. Each\n        array has shape (repetitions, size) with size for that measurement.\n    \"\"\"\n    bits_per_rep = sum(size for _, size in key_sizes)\n    total_bits = repetitions * bits_per_rep\n\n    byte_arr = np.frombuffer(data, dtype='uint8').reshape((len(data), 1))\n    bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1)\n    bits = bits[:total_bits].reshape((repetitions, bits_per_rep))\n\n    results = {}\n    ofs = 0\n    for key, size in key_sizes:\n        results[key] = bits[:, ofs:ofs + size]\n        ofs += size\n\n    return results\n", "path": "cirq/google/programs.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.\nfrom typing import Dict, Iterable, Sequence, Tuple, TYPE_CHECKING\n\nimport numpy as np\n\nfrom cirq.api.google.v1 import operations_pb2\nfrom cirq.google import xmon_gates, xmon_gate_ext\nfrom cirq.google.xmon_device import XmonDevice\nfrom cirq.schedules import Schedule, ScheduledOperation\nfrom cirq.value import Timestamp\n\nif TYPE_CHECKING:\n    from typing import Optional  # pylint: disable=unused-import\n\n\ndef schedule_to_proto(schedule: Schedule) -> Iterable[operations_pb2.Operation]:\n    \"\"\"Convert a schedule into protobufs.\n\n    Args:\n        schedule: The schedule to convert to protobufs. Must contain only gates\n            that can be cast to xmon gates.\n\n    Yields:\n        operations_pb2.Operation\n    \"\"\"\n    last_time_picos = None  # type: Optional[int]\n    for so in schedule.scheduled_operations:\n        gate = xmon_gate_ext.cast(xmon_gates.XmonGate, so.operation.gate)\n        op = gate.to_proto(*so.operation.qubits)\n        time_picos = so.time.raw_picos()\n        if last_time_picos is None:\n            op.incremental_delay_picoseconds = time_picos\n        else:\n            op.incremental_delay_picoseconds = time_picos - last_time_picos\n        last_time_picos = time_picos\n        yield op\n\n\ndef schedule_from_proto(\n        device: XmonDevice,\n        ops: Iterable[operations_pb2.Operation],\n) -> Schedule:\n    \"\"\"Convert protobufs into a Schedule for the given device.\"\"\"\n    scheduled_ops = []\n    last_time_picos = 0\n    for op in ops:\n        time_picos = last_time_picos + op.incremental_delay_picoseconds\n        last_time_picos = time_picos\n        xmon_op = xmon_gates.XmonGate.from_proto(op)\n        scheduled_ops.append(ScheduledOperation.op_at_on(\n            operation=xmon_op,\n            time=Timestamp(picos=time_picos),\n            device=device,\n        ))\n    return Schedule(device, scheduled_ops)\n\n\ndef pack_results(measurements: Sequence[Tuple[str, np.ndarray]]) -> bytes:\n    \"\"\"Pack measurement results into a byte string.\n\n    Args:\n        measurements: A sequence of tuples, one for each measurement, consisting\n            of a string key and an array of boolean data. The data should be\n            a 2-D array indexed by (repetition, qubit_index). All data for all\n            measurements must have the same number of repetitions.\n\n    Returns:\n        Packed bytes, as described in the unpack_results docstring below.\n\n    Raises:\n        ValueError if the measurement data do not have the compatible shapes.\n    \"\"\"\n    if not measurements:\n        return b''\n\n    shapes = [(key, np.shape(data)) for key, data in measurements]\n    if not all(len(shape) == 2 for _, shape in shapes):\n        raise ValueError(\"Expected 2-D data: shapes={}\".format(shapes))\n\n    reps = shapes[0][1][0]\n    if not all(shape[0] == reps for _, shape in shapes):\n        raise ValueError(\n            \"Expected same reps for all keys: shapes={}\".format(shapes))\n\n    bits = np.hstack(np.asarray(data, dtype=bool) for _, data in measurements)\n    bits = bits.reshape(-1)\n\n    # Pad length to multiple of 8 if needed.\n    remainder = len(bits) % 8\n    if remainder:\n        bits = np.pad(bits, (0, 8 - remainder), 'constant')\n\n    # Pack in little-endian bit order.\n    bits = bits.reshape((-1, 8))[:, ::-1]\n    byte_arr = np.packbits(bits, axis=1).reshape(-1)\n\n    return byte_arr.tobytes()\n\n\ndef unpack_results(\n        data: bytes,\n        repetitions: int,\n        key_sizes: Sequence[Tuple[str, int]]\n) -> Dict[str, np.ndarray]:\n    \"\"\"Unpack data from a bitstring into individual measurement results.\n\n    Args:\n        data: Packed measurement results, in the form <rep0><rep1>...\n            where each repetition is <key0_0>..<key0_{size0-1}><key1_0>...\n            with bits packed in little-endian order in each byte.\n        repetitions: number of repetitions.\n        key_sizes: Keys and sizes of the measurements in the data.\n\n    Returns:\n        Dict mapping measurement key to a 2D array of boolean results. Each\n        array has shape (repetitions, size) with size for that measurement.\n    \"\"\"\n    bits_per_rep = sum(size for _, size in key_sizes)\n    total_bits = repetitions * bits_per_rep\n\n    byte_arr = np.frombuffer(data, dtype='uint8').reshape((len(data), 1))\n    bits = np.unpackbits(byte_arr, axis=1)[:, ::-1].reshape(-1).astype(bool)\n    bits = bits[:total_bits].reshape((repetitions, bits_per_rep))\n\n    results = {}\n    ofs = 0\n    for key, size in key_sizes:\n        results[key] = bits[:, ofs:ofs + size]\n        ofs += size\n\n    return results\n", "path": "cirq/google/programs.py"}]}