We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
merge_single_qubit_gates_to_phxz raises IndexError when encountering GlobalPhaseGate
**Description of the issue**

**How to reproduce the issue**

```
cirq.merge_single_qubit_gates_to_phxz(cirq.Circuit(cirq.GlobalPhaseGate(1j).on()))
...
/src/cirq/cirq-core/cirq/linalg/decompositions.py in deconstruct_single_qubit_matrix_into_angles(mat)
     88     """
     89     # Anti-cancel left-vs-right phase along top row.
---> 90     right_phase = cmath.phase(mat[0, 1] * np.conj(mat[0, 0])) + math.pi
     91     mat = np.dot(mat, _phase_matrix(-right_phase))
     92 

IndexError: index 1 is out of bounds for axis 1 with size 1
```

I also checked `merge_single_qubit_gates_to_phased_x_and_z` and it suffers from the same issue.

The problem appears to be that the rewriter passes a 1x1 matrix to `single_qubit_matrix_to_phxz` which expects a 2x2 matrix.

**Cirq version**
0.16.0.dev


--- 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-core/cirq/transformers/merge_single_qubit_gates.py`
Content:
```
1 # Copyright 2022 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 """Transformer passes to combine adjacent single-qubit rotations."""
16 
17 from typing import Optional, TYPE_CHECKING
18 
19 from cirq import protocols, circuits
20 from cirq.transformers.analytical_decompositions import single_qubit_decompositions
21 from cirq.transformers import transformer_api, transformer_primitives, merge_k_qubit_gates
22 
23 if TYPE_CHECKING:
24     import cirq
25 
26 
27 @transformer_api.transformer
28 def merge_single_qubit_gates_to_phased_x_and_z(
29     circuit: 'cirq.AbstractCircuit',
30     *,
31     context: Optional['cirq.TransformerContext'] = None,
32     atol: float = 1e-8,
33 ) -> 'cirq.Circuit':
34     """Replaces runs of single qubit rotations with `cirq.PhasedXPowGate` and `cirq.ZPowGate`.
35 
36     Specifically, any run of non-parameterized single-qubit unitaries will be replaced by an
37     optional PhasedX operation followed by an optional Z operation.
38 
39     Args:
40         circuit: Input circuit to transform. It will not be modified.
41         context: `cirq.TransformerContext` storing common configurable options for transformers.
42         atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be
43             dropped, smaller values increase accuracy.
44 
45     Returns:
46         Copy of the transformed input circuit.
47     """
48 
49     def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':
50         return [
51             g(op.qubits[0])
52             for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(
53                 protocols.unitary(op), atol
54             )
55         ]
56 
57     return merge_k_qubit_gates.merge_k_qubit_unitaries(
58         circuit, k=1, context=context, rewriter=rewriter
59     )
60 
61 
62 @transformer_api.transformer
63 def merge_single_qubit_gates_to_phxz(
64     circuit: 'cirq.AbstractCircuit',
65     *,
66     context: Optional['cirq.TransformerContext'] = None,
67     atol: float = 1e-8,
68 ) -> 'cirq.Circuit':
69     """Replaces runs of single qubit rotations with a single optional `cirq.PhasedXZGate`.
70 
71     Specifically, any run of non-parameterized single-qubit unitaries will be replaced by an
72     optional PhasedXZ.
73 
74     Args:
75         circuit: Input circuit to transform. It will not be modified.
76         context: `cirq.TransformerContext` storing common configurable options for transformers.
77         atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be
78             dropped, smaller values increase accuracy.
79 
80     Returns:
81         Copy of the transformed input circuit.
82     """
83 
84     def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':
85         gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(protocols.unitary(op), atol)
86         return gate(op.qubits[0]) if gate else []
87 
88     return merge_k_qubit_gates.merge_k_qubit_unitaries(
89         circuit, k=1, context=context, rewriter=rewriter
90     )
91 
92 
93 @transformer_api.transformer
94 def merge_single_qubit_moments_to_phxz(
95     circuit: 'cirq.AbstractCircuit',
96     *,
97     context: Optional['cirq.TransformerContext'] = None,
98     atol: float = 1e-8,
99 ) -> 'cirq.Circuit':
100     """Merges adjacent moments with only 1-qubit rotations to a single moment with PhasedXZ gates.
101 
102     Args:
103         circuit: Input circuit to transform. It will not be modified.
104         context: `cirq.TransformerContext` storing common configurable options for transformers.
105         atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be
106             dropped, smaller values increase accuracy.
107 
108     Returns:
109         Copy of the transformed input circuit.
110     """
111     tags_to_ignore = set(context.tags_to_ignore) if context else set()
112 
113     def can_merge_moment(m: 'cirq.Moment'):
114         return all(
115             protocols.num_qubits(op) == 1
116             and protocols.has_unitary(op)
117             and tags_to_ignore.isdisjoint(op.tags)
118             for op in m
119         )
120 
121     def merge_func(m1: 'cirq.Moment', m2: 'cirq.Moment') -> Optional['cirq.Moment']:
122         if not (can_merge_moment(m1) and can_merge_moment(m2)):
123             return None
124         ret_ops = []
125         for q in m1.qubits | m2.qubits:
126             mat = protocols.unitary(circuits.Circuit(m.operation_at(q) or [] for m in [m1, m2]))
127             gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(mat, atol)
128             if gate:
129                 ret_ops.append(gate(q))
130         return circuits.Moment(ret_ops)
131 
132     return transformer_primitives.merge_moments(
133         circuit,
134         merge_func,
135         deep=context.deep if context else False,
136         tags_to_ignore=tuple(tags_to_ignore),
137     ).unfreeze(copy=False)
138
```
--- 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-core/cirq/transformers/merge_single_qubit_gates.py b/cirq-core/cirq/transformers/merge_single_qubit_gates.py
--- a/cirq-core/cirq/transformers/merge_single_qubit_gates.py
+++ b/cirq-core/cirq/transformers/merge_single_qubit_gates.py
@@ -16,7 +16,7 @@
 
 from typing import Optional, TYPE_CHECKING
 
-from cirq import protocols, circuits
+from cirq import circuits, ops, protocols
 from cirq.transformers.analytical_decompositions import single_qubit_decompositions
 from cirq.transformers import transformer_api, transformer_primitives, merge_k_qubit_gates
 
@@ -47,11 +47,12 @@
     """
 
     def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':
+        u = protocols.unitary(op)
+        if protocols.num_qubits(op) == 0:
+            return ops.GlobalPhaseGate(u[0, 0]).on()
         return [
             g(op.qubits[0])
-            for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(
-                protocols.unitary(op), atol
-            )
+            for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(u, atol)
         ]
 
     return merge_k_qubit_gates.merge_k_qubit_unitaries(
@@ -82,7 +83,10 @@
     """
 
     def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':
-        gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(protocols.unitary(op), atol)
+        u = protocols.unitary(op)
+        if protocols.num_qubits(op) == 0:
+            return ops.GlobalPhaseGate(u[0, 0]).on()
+        gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(u, atol)
         return gate(op.qubits[0]) if gate else []
 
     return merge_k_qubit_gates.merge_k_qubit_unitaries(

{"golden_diff": "diff --git a/cirq-core/cirq/transformers/merge_single_qubit_gates.py b/cirq-core/cirq/transformers/merge_single_qubit_gates.py\n--- a/cirq-core/cirq/transformers/merge_single_qubit_gates.py\n+++ b/cirq-core/cirq/transformers/merge_single_qubit_gates.py\n@@ -16,7 +16,7 @@\n \n from typing import Optional, TYPE_CHECKING\n \n-from cirq import protocols, circuits\n+from cirq import circuits, ops, protocols\n from cirq.transformers.analytical_decompositions import single_qubit_decompositions\n from cirq.transformers import transformer_api, transformer_primitives, merge_k_qubit_gates\n \n@@ -47,11 +47,12 @@\n     \"\"\"\n \n     def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':\n+        u = protocols.unitary(op)\n+        if protocols.num_qubits(op) == 0:\n+            return ops.GlobalPhaseGate(u[0, 0]).on()\n         return [\n             g(op.qubits[0])\n-            for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(\n-                protocols.unitary(op), atol\n-            )\n+            for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(u, atol)\n         ]\n \n     return merge_k_qubit_gates.merge_k_qubit_unitaries(\n@@ -82,7 +83,10 @@\n     \"\"\"\n \n     def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':\n-        gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(protocols.unitary(op), atol)\n+        u = protocols.unitary(op)\n+        if protocols.num_qubits(op) == 0:\n+            return ops.GlobalPhaseGate(u[0, 0]).on()\n+        gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(u, atol)\n         return gate(op.qubits[0]) if gate else []\n \n     return merge_k_qubit_gates.merge_k_qubit_unitaries(\n", "issue": "merge_single_qubit_gates_to_phxz raises IndexError when encountering GlobalPhaseGate\n**Description of the issue**\r\n\r\n**How to reproduce the issue**\r\n\r\n```\r\ncirq.merge_single_qubit_gates_to_phxz(cirq.Circuit(cirq.GlobalPhaseGate(1j).on()))\r\n...\r\n/src/cirq/cirq-core/cirq/linalg/decompositions.py in deconstruct_single_qubit_matrix_into_angles(mat)\r\n     88     \"\"\"\r\n     89     # Anti-cancel left-vs-right phase along top row.\r\n---> 90     right_phase = cmath.phase(mat[0, 1] * np.conj(mat[0, 0])) + math.pi\r\n     91     mat = np.dot(mat, _phase_matrix(-right_phase))\r\n     92 \r\n\r\nIndexError: index 1 is out of bounds for axis 1 with size 1\r\n```\r\n\r\nI also checked `merge_single_qubit_gates_to_phased_x_and_z` and it suffers from the same issue.\r\n\r\nThe problem appears to be that the rewriter passes a 1x1 matrix to `single_qubit_matrix_to_phxz` which expects a 2x2 matrix.\r\n\r\n**Cirq version**\r\n0.16.0.dev\r\n\n", "before_files": [{"content": "# Copyright 2022 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\n\"\"\"Transformer passes to combine adjacent single-qubit rotations.\"\"\"\n\nfrom typing import Optional, TYPE_CHECKING\n\nfrom cirq import protocols, circuits\nfrom cirq.transformers.analytical_decompositions import single_qubit_decompositions\nfrom cirq.transformers import transformer_api, transformer_primitives, merge_k_qubit_gates\n\nif TYPE_CHECKING:\n    import cirq\n\n\n@transformer_api.transformer\ndef merge_single_qubit_gates_to_phased_x_and_z(\n    circuit: 'cirq.AbstractCircuit',\n    *,\n    context: Optional['cirq.TransformerContext'] = None,\n    atol: float = 1e-8,\n) -> 'cirq.Circuit':\n    \"\"\"Replaces runs of single qubit rotations with `cirq.PhasedXPowGate` and `cirq.ZPowGate`.\n\n    Specifically, any run of non-parameterized single-qubit unitaries will be replaced by an\n    optional PhasedX operation followed by an optional Z operation.\n\n    Args:\n        circuit: Input circuit to transform. It will not be modified.\n        context: `cirq.TransformerContext` storing common configurable options for transformers.\n        atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be\n            dropped, smaller values increase accuracy.\n\n    Returns:\n        Copy of the transformed input circuit.\n    \"\"\"\n\n    def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':\n        return [\n            g(op.qubits[0])\n            for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(\n                protocols.unitary(op), atol\n            )\n        ]\n\n    return merge_k_qubit_gates.merge_k_qubit_unitaries(\n        circuit, k=1, context=context, rewriter=rewriter\n    )\n\n\n@transformer_api.transformer\ndef merge_single_qubit_gates_to_phxz(\n    circuit: 'cirq.AbstractCircuit',\n    *,\n    context: Optional['cirq.TransformerContext'] = None,\n    atol: float = 1e-8,\n) -> 'cirq.Circuit':\n    \"\"\"Replaces runs of single qubit rotations with a single optional `cirq.PhasedXZGate`.\n\n    Specifically, any run of non-parameterized single-qubit unitaries will be replaced by an\n    optional PhasedXZ.\n\n    Args:\n        circuit: Input circuit to transform. It will not be modified.\n        context: `cirq.TransformerContext` storing common configurable options for transformers.\n        atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be\n            dropped, smaller values increase accuracy.\n\n    Returns:\n        Copy of the transformed input circuit.\n    \"\"\"\n\n    def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':\n        gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(protocols.unitary(op), atol)\n        return gate(op.qubits[0]) if gate else []\n\n    return merge_k_qubit_gates.merge_k_qubit_unitaries(\n        circuit, k=1, context=context, rewriter=rewriter\n    )\n\n\n@transformer_api.transformer\ndef merge_single_qubit_moments_to_phxz(\n    circuit: 'cirq.AbstractCircuit',\n    *,\n    context: Optional['cirq.TransformerContext'] = None,\n    atol: float = 1e-8,\n) -> 'cirq.Circuit':\n    \"\"\"Merges adjacent moments with only 1-qubit rotations to a single moment with PhasedXZ gates.\n\n    Args:\n        circuit: Input circuit to transform. It will not be modified.\n        context: `cirq.TransformerContext` storing common configurable options for transformers.\n        atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be\n            dropped, smaller values increase accuracy.\n\n    Returns:\n        Copy of the transformed input circuit.\n    \"\"\"\n    tags_to_ignore = set(context.tags_to_ignore) if context else set()\n\n    def can_merge_moment(m: 'cirq.Moment'):\n        return all(\n            protocols.num_qubits(op) == 1\n            and protocols.has_unitary(op)\n            and tags_to_ignore.isdisjoint(op.tags)\n            for op in m\n        )\n\n    def merge_func(m1: 'cirq.Moment', m2: 'cirq.Moment') -> Optional['cirq.Moment']:\n        if not (can_merge_moment(m1) and can_merge_moment(m2)):\n            return None\n        ret_ops = []\n        for q in m1.qubits | m2.qubits:\n            mat = protocols.unitary(circuits.Circuit(m.operation_at(q) or [] for m in [m1, m2]))\n            gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(mat, atol)\n            if gate:\n                ret_ops.append(gate(q))\n        return circuits.Moment(ret_ops)\n\n    return transformer_primitives.merge_moments(\n        circuit,\n        merge_func,\n        deep=context.deep if context else False,\n        tags_to_ignore=tuple(tags_to_ignore),\n    ).unfreeze(copy=False)\n", "path": "cirq-core/cirq/transformers/merge_single_qubit_gates.py"}], "after_files": [{"content": "# Copyright 2022 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\n\"\"\"Transformer passes to combine adjacent single-qubit rotations.\"\"\"\n\nfrom typing import Optional, TYPE_CHECKING\n\nfrom cirq import circuits, ops, protocols\nfrom cirq.transformers.analytical_decompositions import single_qubit_decompositions\nfrom cirq.transformers import transformer_api, transformer_primitives, merge_k_qubit_gates\n\nif TYPE_CHECKING:\n    import cirq\n\n\n@transformer_api.transformer\ndef merge_single_qubit_gates_to_phased_x_and_z(\n    circuit: 'cirq.AbstractCircuit',\n    *,\n    context: Optional['cirq.TransformerContext'] = None,\n    atol: float = 1e-8,\n) -> 'cirq.Circuit':\n    \"\"\"Replaces runs of single qubit rotations with `cirq.PhasedXPowGate` and `cirq.ZPowGate`.\n\n    Specifically, any run of non-parameterized single-qubit unitaries will be replaced by an\n    optional PhasedX operation followed by an optional Z operation.\n\n    Args:\n        circuit: Input circuit to transform. It will not be modified.\n        context: `cirq.TransformerContext` storing common configurable options for transformers.\n        atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be\n            dropped, smaller values increase accuracy.\n\n    Returns:\n        Copy of the transformed input circuit.\n    \"\"\"\n\n    def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':\n        u = protocols.unitary(op)\n        if protocols.num_qubits(op) == 0:\n            return ops.GlobalPhaseGate(u[0, 0]).on()\n        return [\n            g(op.qubits[0])\n            for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(u, atol)\n        ]\n\n    return merge_k_qubit_gates.merge_k_qubit_unitaries(\n        circuit, k=1, context=context, rewriter=rewriter\n    )\n\n\n@transformer_api.transformer\ndef merge_single_qubit_gates_to_phxz(\n    circuit: 'cirq.AbstractCircuit',\n    *,\n    context: Optional['cirq.TransformerContext'] = None,\n    atol: float = 1e-8,\n) -> 'cirq.Circuit':\n    \"\"\"Replaces runs of single qubit rotations with a single optional `cirq.PhasedXZGate`.\n\n    Specifically, any run of non-parameterized single-qubit unitaries will be replaced by an\n    optional PhasedXZ.\n\n    Args:\n        circuit: Input circuit to transform. It will not be modified.\n        context: `cirq.TransformerContext` storing common configurable options for transformers.\n        atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be\n            dropped, smaller values increase accuracy.\n\n    Returns:\n        Copy of the transformed input circuit.\n    \"\"\"\n\n    def rewriter(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE':\n        u = protocols.unitary(op)\n        if protocols.num_qubits(op) == 0:\n            return ops.GlobalPhaseGate(u[0, 0]).on()\n        gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(u, atol)\n        return gate(op.qubits[0]) if gate else []\n\n    return merge_k_qubit_gates.merge_k_qubit_unitaries(\n        circuit, k=1, context=context, rewriter=rewriter\n    )\n\n\n@transformer_api.transformer\ndef merge_single_qubit_moments_to_phxz(\n    circuit: 'cirq.AbstractCircuit',\n    *,\n    context: Optional['cirq.TransformerContext'] = None,\n    atol: float = 1e-8,\n) -> 'cirq.Circuit':\n    \"\"\"Merges adjacent moments with only 1-qubit rotations to a single moment with PhasedXZ gates.\n\n    Args:\n        circuit: Input circuit to transform. It will not be modified.\n        context: `cirq.TransformerContext` storing common configurable options for transformers.\n        atol: Absolute tolerance to angle error. Larger values allow more negligible gates to be\n            dropped, smaller values increase accuracy.\n\n    Returns:\n        Copy of the transformed input circuit.\n    \"\"\"\n    tags_to_ignore = set(context.tags_to_ignore) if context else set()\n\n    def can_merge_moment(m: 'cirq.Moment'):\n        return all(\n            protocols.num_qubits(op) == 1\n            and protocols.has_unitary(op)\n            and tags_to_ignore.isdisjoint(op.tags)\n            for op in m\n        )\n\n    def merge_func(m1: 'cirq.Moment', m2: 'cirq.Moment') -> Optional['cirq.Moment']:\n        if not (can_merge_moment(m1) and can_merge_moment(m2)):\n            return None\n        ret_ops = []\n        for q in m1.qubits | m2.qubits:\n            mat = protocols.unitary(circuits.Circuit(m.operation_at(q) or [] for m in [m1, m2]))\n            gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(mat, atol)\n            if gate:\n                ret_ops.append(gate(q))\n        return circuits.Moment(ret_ops)\n\n    return transformer_primitives.merge_moments(\n        circuit,\n        merge_func,\n        deep=context.deep if context else False,\n        tags_to_ignore=tuple(tags_to_ignore),\n    ).unfreeze(copy=False)\n", "path": "cirq-core/cirq/transformers/merge_single_qubit_gates.py"}]}