Repository: quantumlib/Cirq

Issue:
Add PhaseXZ (de)serializer to standard (de)serializers
After #2598 is in and the gates are supported in the server.


Discussion:

Resolving patch:
diff --git a/cirq/google/common_serializers.py b/cirq/google/common_serializers.py
--- a/cirq/google/common_serializers.py
+++ b/cirq/google/common_serializers.py
@@ -59,47 +59,87 @@ def _near_mod_2(e, t, atol=1e-8):
         gate_type=ops.PhasedXPowGate,
         serialized_gate_id='xy',
         args=[
-            op_serializer.SerializingArg(serialized_name='axis_half_turns',
-                                         serialized_type=float,
-                                         gate_getter='phase_exponent'),
-            op_serializer.SerializingArg(serialized_name='half_turns',
-                                         serialized_type=float,
-                                         gate_getter='exponent'),
-        ]),
+            op_serializer.SerializingArg(
+                serialized_name='axis_half_turns',
+                serialized_type=float,
+                gate_getter='phase_exponent',
+            ),
+            op_serializer.SerializingArg(
+                serialized_name='half_turns',
+                serialized_type=float,
+                gate_getter='exponent',
+            ),
+        ],
+    ),
     op_serializer.GateOpSerializer(
         gate_type=ops.XPowGate,
         serialized_gate_id='xy',
         args=[
-            op_serializer.SerializingArg(serialized_name='axis_half_turns',
-                                         serialized_type=float,
-                                         gate_getter=lambda x: 0.0),
-            op_serializer.SerializingArg(serialized_name='half_turns',
-                                         serialized_type=float,
-                                         gate_getter='exponent'),
-        ]),
+            op_serializer.SerializingArg(
+                serialized_name='axis_half_turns',
+                serialized_type=float,
+                gate_getter=lambda x: 0.0,
+            ),
+            op_serializer.SerializingArg(
+                serialized_name='half_turns',
+                serialized_type=float,
+                gate_getter='exponent',
+            ),
+        ],
+    ),
     op_serializer.GateOpSerializer(
         gate_type=ops.YPowGate,
         serialized_gate_id='xy',
         args=[
-            op_serializer.SerializingArg(serialized_name='axis_half_turns',
-                                         serialized_type=float,
-                                         gate_getter=lambda x: 0.5),
-            op_serializer.SerializingArg(serialized_name='half_turns',
-                                         serialized_type=float,
-                                         gate_getter='exponent'),
-        ]),
+            op_serializer.SerializingArg(
+                serialized_name='axis_half_turns',
+                serialized_type=float,
+                gate_getter=lambda x: 0.5,
+            ),
+            op_serializer.SerializingArg(
+                serialized_name='half_turns',
+                serialized_type=float,
+                gate_getter='exponent',
+            ),
+        ],
+    ),
     op_serializer.GateOpSerializer(
         gate_type=ops.ZPowGate,
         serialized_gate_id='z',
         args=[
-            op_serializer.SerializingArg(serialized_name='half_turns',
-                                         serialized_type=float,
-                                         gate_getter='exponent'),
+            op_serializer.SerializingArg(
+                serialized_name='half_turns',
+                serialized_type=float,
+                gate_getter='exponent',
+            ),
             op_serializer.SerializingArg(
                 serialized_name='type',
                 serialized_type=str,
-                gate_getter=lambda x: 'virtual_propagates_forward'),
-        ])
+                gate_getter=lambda x: 'virtual_propagates_forward',
+            ),
+        ],
+    ),
+    op_serializer.GateOpSerializer(
+        gate_type=ops.PhasedXZGate,
+        serialized_gate_id='xyz',
+        args=[
+            op_serializer.SerializingArg(
+                serialized_name='x_exponent',
+                serialized_type=float,
+                gate_getter='x_exponent',
+            ),
+            op_serializer.SerializingArg(
+                serialized_name='z_exponent',
+                serialized_type=float,
+                gate_getter='z_exponent',
+            ),
+            op_serializer.SerializingArg(
+                serialized_name='axis_phase_exponent',
+                serialized_type=float,
+                gate_getter='axis_phase_exponent',
+            ),
+        ],
+    ),
 ]
 
 
@@ -113,66 +153,45 @@ def _near_mod_2(e, t, atol=1e-8):
         args=[
             op_deserializer.DeserializingArg(
                 serialized_name='axis_half_turns',
-                constructor_arg_name='phase_exponent'),
-            op_deserializer.DeserializingArg(serialized_name='half_turns',
-                                             constructor_arg_name='exponent')
-        ]),
-    op_deserializer.GateOpDeserializer(serialized_gate_id='z',
-                                       gate_constructor=ops.ZPowGate,
-                                       args=[
-                                           op_deserializer.DeserializingArg(
-                                               serialized_name='half_turns',
-                                               constructor_arg_name='exponent')
-                                       ]),
+                constructor_arg_name='phase_exponent',
+            ),
+            op_deserializer.DeserializingArg(
+                serialized_name='half_turns',
+                constructor_arg_name='exponent',
+            ),
+        ],
+    ),
+    op_deserializer.GateOpDeserializer(
+        serialized_gate_id='z',
+        gate_constructor=ops.ZPowGate,
+        args=[
+            op_deserializer.DeserializingArg(
+                serialized_name='half_turns',
+                constructor_arg_name='exponent',
+            ),
+        ],
+    ),
+    op_deserializer.GateOpDeserializer(
+        serialized_gate_id='xyz',
+        gate_constructor=ops.PhasedXZGate,
+        args=[
+            op_deserializer.DeserializingArg(
+                serialized_name='x_exponent',
+                constructor_arg_name='x_exponent',
+            ),
+            op_deserializer.DeserializingArg(
+                serialized_name='z_exponent',
+                constructor_arg_name='z_exponent',
+            ),
+            op_deserializer.DeserializingArg(
+                serialized_name='axis_phase_exponent',
+                constructor_arg_name='axis_phase_exponent',
+            ),
+        ],
+    ),
 ]
 
 
-#
-# PhasedXZ gate (de)serializer
-# TODO(#2602): Move to SINGLE_QUBIT_(DE)SERIALIZERS when server support is in.
-#
-
-PHASED_X_Z_SERIALIZER = op_serializer.GateOpSerializer(
-    gate_type=ops.PhasedXZGate,
-    serialized_gate_id='xyz',
-    args=[
-        op_serializer.SerializingArg(
-            serialized_name='x_exponent',
-            serialized_type=float,
-            gate_getter='x_exponent',
-        ),
-        op_serializer.SerializingArg(
-            serialized_name='z_exponent',
-            serialized_type=float,
-            gate_getter='z_exponent',
-        ),
-        op_serializer.SerializingArg(
-            serialized_name='axis_phase_exponent',
-            serialized_type=float,
-            gate_getter='axis_phase_exponent',
-        ),
-    ],
-)
-
-PHASED_X_Z_DESERIALIZER = op_deserializer.GateOpDeserializer(
-    serialized_gate_id='xyz',
-    gate_constructor=ops.PhasedXZGate,
-    args=[
-        op_deserializer.DeserializingArg(
-            serialized_name='x_exponent',
-            constructor_arg_name='x_exponent',
-        ),
-        op_deserializer.DeserializingArg(
-            serialized_name='z_exponent',
-            constructor_arg_name='z_exponent',
-        ),
-        op_deserializer.DeserializingArg(
-            serialized_name='axis_phase_exponent',
-            constructor_arg_name='axis_phase_exponent',
-        ),
-    ],
-)
-
 #
 # Measurement Serializer and Deserializer
 #


Test patch:
diff --git a/cirq/google/common_serializers_test.py b/cirq/google/common_serializers_test.py
--- a/cirq/google/common_serializers_test.py
+++ b/cirq/google/common_serializers_test.py
@@ -244,10 +244,6 @@ def test_serialize_deserialize_arbitrary_xyz(
         z_exponent,
         axis_phase_exponent,
 ):
-    gateset = cg.serializable_gate_set.SerializableGateSet(
-        gate_set_name='test_xyz',
-        serializers=([cgc.PHASED_X_Z_SERIALIZER]),
-        deserializers=([cgc.PHASED_X_Z_DESERIALIZER]))
     gate = cirq.PhasedXZGate(
         x_exponent=x_exponent,
         z_exponent=z_exponent,
@@ -279,8 +275,8 @@ def test_serialize_deserialize_arbitrary_xyz(
             'id': '1_2'
         }]
     }
-    assert gateset.serialize_op_dict(op) == expected
-    deserialized_op = gateset.deserialize_op_dict(expected)
+    assert SINGLE_QUBIT_GATE_SET.serialize_op_dict(op) == expected
+    deserialized_op = SINGLE_QUBIT_GATE_SET.deserialize_op_dict(expected)
     cirq.testing.assert_allclose_up_to_global_phase(
         cirq.unitary(deserialized_op),
         cirq.unitary(op),
diff --git a/cirq/google/devices/known_devices_test.py b/cirq/google/devices/known_devices_test.py
--- a/cirq/google/devices/known_devices_test.py
+++ b/cirq/google/devices/known_devices_test.py
@@ -57,6 +57,22 @@ def test_foxtail_device_proto():
       type: STRING
     }
   }
+  valid_gates {
+    id: "xyz"
+    number_of_qubits: 1
+    valid_args {
+      name: "x_exponent"
+      type: FLOAT
+    }
+    valid_args {
+      name: "z_exponent"
+      type: FLOAT
+    }
+    valid_args {
+      name: "axis_phase_exponent"
+      type: FLOAT
+    }
+  }
   valid_gates {
     id: "cz"
     number_of_qubits: 2
@@ -286,6 +302,22 @@ def test_multiple_gate_sets():
       type: STRING
     }
   }
+  valid_gates {
+    id: "xyz"
+    number_of_qubits: 1
+    valid_args {
+      name: "x_exponent"
+      type: FLOAT
+    }
+    valid_args {
+      name: "z_exponent"
+      type: FLOAT
+    }
+    valid_args {
+      name: "axis_phase_exponent"
+      type: FLOAT
+    }
+  }
   valid_gates {
     id: "cz"
     number_of_qubits: 2