From 6e52a548b4737cc690d758dd367bd8e5e0e46d56 Mon Sep 17 00:00:00 2001 From: Nour Yosri Date: Thu, 18 Jan 2024 15:13:41 -0800 Subject: [PATCH] Support serialization of SingleQubitCliffordGate --- cirq-google/cirq_google/api/v2/program.proto | 13 +++ cirq-google/cirq_google/api/v2/program_pb2.py | 96 ++++++++++--------- .../cirq_google/api/v2/program_pb2.pyi | 65 ++++++++++++- .../serialization/arg_func_langs.py | 47 +++++++++ .../serialization/arg_func_langs_test.py | 27 ++++++ .../serialization/circuit_serializer.py | 12 ++- .../serialization/circuit_serializer_test.py | 26 +++++ 7 files changed, 236 insertions(+), 50 deletions(-) diff --git a/cirq-google/cirq_google/api/v2/program.proto b/cirq-google/cirq_google/api/v2/program.proto index 9133dc03788..da51dd4eef3 100644 --- a/cirq-google/cirq_google/api/v2/program.proto +++ b/cirq-google/cirq_google/api/v2/program.proto @@ -208,6 +208,7 @@ message Operation { MeasurementGate measurementgate = 15; WaitGate waitgate = 16; InternalGate internalgate = 17; + SingleQubitCliffordGate singlequbitcliffordgate = 18; } // Map from the argument name to the Argument needed to fully specify @@ -424,4 +425,16 @@ message InternalGate{ string module = 2; // Gate module. int32 num_qubits = 3; // Number of qubits. Required during deserialization. map gate_args = 4; // Gate args. +} + +message CliffordTableau { + optional int32 num_qubits = 1; + optional int32 initial_state = 2; + optional bytes rs = 3; + optional bytes xs = 4; + optional bytes zs = 5; +} + +message SingleQubitCliffordGate { + CliffordTableau tableau = 1; } \ No newline at end of file diff --git a/cirq-google/cirq_google/api/v2/program_pb2.py b/cirq-google/cirq_google/api/v2/program_pb2.py index 2440805d87a..00bfd723833 100644 --- a/cirq-google/cirq_google/api/v2/program_pb2.py +++ b/cirq-google/cirq_google/api/v2/program_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v2/program.proto\x12\x12\x63irq.google.api.v2\"\xd7\x01\n\x07Program\x12.\n\x08language\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.Language\x12.\n\x07\x63ircuit\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12\x30\n\x08schedule\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.ScheduleH\x00\x12/\n\tconstants\x18\x04 \x03(\x0b\x32\x1c.cirq.google.api.v2.ConstantB\t\n\x07program\"\x93\x01\n\x08\x43onstant\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x34\n\rcircuit_value\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12*\n\x05qubit\x18\x03 \x01(\x0b\x32\x19.cirq.google.api.v2.QubitH\x00\x42\r\n\x0b\x63onst_value\"\xd4\x01\n\x07\x43ircuit\x12K\n\x13scheduling_strategy\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.Circuit.SchedulingStrategy\x12+\n\x07moments\x18\x02 \x03(\x0b\x32\x1a.cirq.google.api.v2.Moment\"O\n\x12SchedulingStrategy\x12#\n\x1fSCHEDULING_STRATEGY_UNSPECIFIED\x10\x00\x12\x14\n\x10MOMENT_BY_MOMENT\x10\x01\"}\n\x06Moment\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12@\n\x12\x63ircuit_operations\x18\x02 \x03(\x0b\x32$.cirq.google.api.v2.CircuitOperation\"P\n\x08Schedule\x12\x44\n\x14scheduled_operations\x18\x03 \x03(\x0b\x32&.cirq.google.api.v2.ScheduledOperation\"`\n\x12ScheduledOperation\x12\x30\n\toperation\x18\x01 \x01(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12\x18\n\x10start_time_picos\x18\x02 \x01(\x03\"?\n\x08Language\x12\x14\n\x08gate_set\x18\x01 \x01(\tB\x02\x18\x01\x12\x1d\n\x15\x61rg_function_language\x18\x02 \x01(\t\"k\n\x08\x46loatArg\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x42\x05\n\x03\x61rg\":\n\x08XPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\":\n\x08YPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"Q\n\x08ZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x15\n\ris_physical_z\x18\x02 \x01(\x08\"v\n\x0ePhasedXPowGate\x12\x34\n\x0ephase_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12.\n\x08\x65xponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xad\x01\n\x0cPhasedXZGate\x12\x30\n\nx_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x30\n\nz_exponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x39\n\x13\x61xis_phase_exponent\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\";\n\tCZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"b\n\x08\x46SimGate\x12+\n\x05theta\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12)\n\x03phi\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\">\n\x0cISwapPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"e\n\x0fMeasurementGate\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12,\n\x0binvert_mask\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"@\n\x08WaitGate\x12\x34\n\x0e\x64uration_nanos\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xa9\x07\n\tOperation\x12*\n\x04gate\x18\x01 \x01(\x0b\x32\x18.cirq.google.api.v2.GateB\x02\x18\x01\x12\x30\n\x08xpowgate\x18\x07 \x01(\x0b\x32\x1c.cirq.google.api.v2.XPowGateH\x00\x12\x30\n\x08ypowgate\x18\x08 \x01(\x0b\x32\x1c.cirq.google.api.v2.YPowGateH\x00\x12\x30\n\x08zpowgate\x18\t \x01(\x0b\x32\x1c.cirq.google.api.v2.ZPowGateH\x00\x12<\n\x0ephasedxpowgate\x18\n \x01(\x0b\x32\".cirq.google.api.v2.PhasedXPowGateH\x00\x12\x38\n\x0cphasedxzgate\x18\x0b \x01(\x0b\x32 .cirq.google.api.v2.PhasedXZGateH\x00\x12\x32\n\tczpowgate\x18\x0c \x01(\x0b\x32\x1d.cirq.google.api.v2.CZPowGateH\x00\x12\x30\n\x08\x66simgate\x18\r \x01(\x0b\x32\x1c.cirq.google.api.v2.FSimGateH\x00\x12\x38\n\x0ciswappowgate\x18\x0e \x01(\x0b\x32 .cirq.google.api.v2.ISwapPowGateH\x00\x12>\n\x0fmeasurementgate\x18\x0f \x01(\x0b\x32#.cirq.google.api.v2.MeasurementGateH\x00\x12\x30\n\x08waitgate\x18\x10 \x01(\x0b\x32\x1c.cirq.google.api.v2.WaitGateH\x00\x12\x38\n\x0cinternalgate\x18\x11 \x01(\x0b\x32 .cirq.google.api.v2.InternalGateH\x00\x12\x39\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\'.cirq.google.api.v2.Operation.ArgsEntryB\x02\x18\x01\x12)\n\x06qubits\x18\x03 \x03(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12\x1c\n\x14qubit_constant_index\x18\x06 \x03(\x05\x12\x15\n\x0btoken_value\x18\x04 \x01(\tH\x01\x12\x1e\n\x14token_constant_index\x18\x05 \x01(\x05H\x01\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42\x0c\n\ngate_valueB\x07\n\x05token\"\x12\n\x04Gate\x12\n\n\x02id\x18\x01 \x01(\t\"\x13\n\x05Qubit\x12\n\n\x02id\x18\x02 \x01(\t\"\x9c\x01\n\x03\x41rg\x12\x31\n\targ_value\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.ArgValueH\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x12\x18\n\x0e\x63onstant_index\x18\x04 \x01(\x05H\x00\x42\x05\n\x03\x61rg\"\xcf\x02\n\x08\x41rgValue\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12:\n\x0b\x62ool_values\x18\x02 \x01(\x0b\x32#.cirq.google.api.v2.RepeatedBooleanH\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x39\n\x0cint64_values\x18\x05 \x01(\x0b\x32!.cirq.google.api.v2.RepeatedInt64H\x00\x12;\n\rdouble_values\x18\x06 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedDoubleH\x00\x12;\n\rstring_values\x18\x07 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedStringH\x00\x42\x0b\n\targ_value\"\x1f\n\rRepeatedInt64\x12\x0e\n\x06values\x18\x01 \x03(\x03\" \n\x0eRepeatedDouble\x12\x0e\n\x06values\x18\x01 \x03(\x01\" \n\x0eRepeatedString\x12\x0e\n\x06values\x18\x01 \x03(\t\"!\n\x0fRepeatedBoolean\x12\x0e\n\x06values\x18\x01 \x03(\x08\"B\n\x0b\x41rgFunction\x12\x0c\n\x04type\x18\x01 \x01(\t\x12%\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xaf\x02\n\x10\x43ircuitOperation\x12\x1e\n\x16\x63ircuit_constant_index\x18\x01 \x01(\x05\x12M\n\x18repetition_specification\x18\x02 \x01(\x0b\x32+.cirq.google.api.v2.RepetitionSpecification\x12\x33\n\tqubit_map\x18\x03 \x01(\x0b\x32 .cirq.google.api.v2.QubitMapping\x12\x46\n\x13measurement_key_map\x18\x04 \x01(\x0b\x32).cirq.google.api.v2.MeasurementKeyMapping\x12/\n\x07\x61rg_map\x18\x05 \x01(\x0b\x32\x1e.cirq.google.api.v2.ArgMapping\"\xbc\x01\n\x17RepetitionSpecification\x12S\n\x0erepetition_ids\x18\x01 \x01(\x0b\x32\x39.cirq.google.api.v2.RepetitionSpecification.RepetitionIdsH\x00\x12\x1a\n\x10repetition_count\x18\x02 \x01(\x05H\x00\x1a\x1c\n\rRepetitionIds\x12\x0b\n\x03ids\x18\x01 \x03(\tB\x12\n\x10repetition_value\"\xac\x01\n\x0cQubitMapping\x12<\n\x07\x65ntries\x18\x01 \x03(\x0b\x32+.cirq.google.api.v2.QubitMapping.QubitEntry\x1a^\n\nQubitEntry\x12&\n\x03key\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\"$\n\x0eMeasurementKey\x12\x12\n\nstring_key\x18\x01 \x01(\t\"\xe2\x01\n\x15MeasurementKeyMapping\x12N\n\x07\x65ntries\x18\x01 \x03(\x0b\x32=.cirq.google.api.v2.MeasurementKeyMapping.MeasurementKeyEntry\x1ay\n\x13MeasurementKeyEntry\x12/\n\x03key\x18\x01 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\x12\x31\n\x05value\x18\x02 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\"\xa0\x01\n\nArgMapping\x12\x38\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\'.cirq.google.api.v2.ArgMapping.ArgEntry\x1aX\n\x08\x41rgEntry\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xcd\x01\n\x0cInternalGate\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x12\n\nnum_qubits\x18\x03 \x01(\x05\x12\x41\n\tgate_args\x18\x04 \x03(\x0b\x32..cirq.google.api.v2.InternalGate.GateArgsEntry\x1aH\n\rGateArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42/\n\x1d\x63om.google.cirq.google.api.v2B\x0cProgramProtoP\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v2/program.proto\x12\x12\x63irq.google.api.v2\"\xd7\x01\n\x07Program\x12.\n\x08language\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.Language\x12.\n\x07\x63ircuit\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12\x30\n\x08schedule\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.ScheduleH\x00\x12/\n\tconstants\x18\x04 \x03(\x0b\x32\x1c.cirq.google.api.v2.ConstantB\t\n\x07program\"\x93\x01\n\x08\x43onstant\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x34\n\rcircuit_value\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12*\n\x05qubit\x18\x03 \x01(\x0b\x32\x19.cirq.google.api.v2.QubitH\x00\x42\r\n\x0b\x63onst_value\"\xd4\x01\n\x07\x43ircuit\x12K\n\x13scheduling_strategy\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.Circuit.SchedulingStrategy\x12+\n\x07moments\x18\x02 \x03(\x0b\x32\x1a.cirq.google.api.v2.Moment\"O\n\x12SchedulingStrategy\x12#\n\x1fSCHEDULING_STRATEGY_UNSPECIFIED\x10\x00\x12\x14\n\x10MOMENT_BY_MOMENT\x10\x01\"}\n\x06Moment\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12@\n\x12\x63ircuit_operations\x18\x02 \x03(\x0b\x32$.cirq.google.api.v2.CircuitOperation\"P\n\x08Schedule\x12\x44\n\x14scheduled_operations\x18\x03 \x03(\x0b\x32&.cirq.google.api.v2.ScheduledOperation\"`\n\x12ScheduledOperation\x12\x30\n\toperation\x18\x01 \x01(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12\x18\n\x10start_time_picos\x18\x02 \x01(\x03\"?\n\x08Language\x12\x14\n\x08gate_set\x18\x01 \x01(\tB\x02\x18\x01\x12\x1d\n\x15\x61rg_function_language\x18\x02 \x01(\t\"k\n\x08\x46loatArg\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x42\x05\n\x03\x61rg\":\n\x08XPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\":\n\x08YPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"Q\n\x08ZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x15\n\ris_physical_z\x18\x02 \x01(\x08\"v\n\x0ePhasedXPowGate\x12\x34\n\x0ephase_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12.\n\x08\x65xponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xad\x01\n\x0cPhasedXZGate\x12\x30\n\nx_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x30\n\nz_exponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x39\n\x13\x61xis_phase_exponent\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\";\n\tCZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"b\n\x08\x46SimGate\x12+\n\x05theta\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12)\n\x03phi\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\">\n\x0cISwapPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"e\n\x0fMeasurementGate\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12,\n\x0binvert_mask\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"@\n\x08WaitGate\x12\x34\n\x0e\x64uration_nanos\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xf9\x07\n\tOperation\x12*\n\x04gate\x18\x01 \x01(\x0b\x32\x18.cirq.google.api.v2.GateB\x02\x18\x01\x12\x30\n\x08xpowgate\x18\x07 \x01(\x0b\x32\x1c.cirq.google.api.v2.XPowGateH\x00\x12\x30\n\x08ypowgate\x18\x08 \x01(\x0b\x32\x1c.cirq.google.api.v2.YPowGateH\x00\x12\x30\n\x08zpowgate\x18\t \x01(\x0b\x32\x1c.cirq.google.api.v2.ZPowGateH\x00\x12<\n\x0ephasedxpowgate\x18\n \x01(\x0b\x32\".cirq.google.api.v2.PhasedXPowGateH\x00\x12\x38\n\x0cphasedxzgate\x18\x0b \x01(\x0b\x32 .cirq.google.api.v2.PhasedXZGateH\x00\x12\x32\n\tczpowgate\x18\x0c \x01(\x0b\x32\x1d.cirq.google.api.v2.CZPowGateH\x00\x12\x30\n\x08\x66simgate\x18\r \x01(\x0b\x32\x1c.cirq.google.api.v2.FSimGateH\x00\x12\x38\n\x0ciswappowgate\x18\x0e \x01(\x0b\x32 .cirq.google.api.v2.ISwapPowGateH\x00\x12>\n\x0fmeasurementgate\x18\x0f \x01(\x0b\x32#.cirq.google.api.v2.MeasurementGateH\x00\x12\x30\n\x08waitgate\x18\x10 \x01(\x0b\x32\x1c.cirq.google.api.v2.WaitGateH\x00\x12\x38\n\x0cinternalgate\x18\x11 \x01(\x0b\x32 .cirq.google.api.v2.InternalGateH\x00\x12N\n\x17singlequbitcliffordgate\x18\x12 \x01(\x0b\x32+.cirq.google.api.v2.SingleQubitCliffordGateH\x00\x12\x39\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\'.cirq.google.api.v2.Operation.ArgsEntryB\x02\x18\x01\x12)\n\x06qubits\x18\x03 \x03(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12\x1c\n\x14qubit_constant_index\x18\x06 \x03(\x05\x12\x15\n\x0btoken_value\x18\x04 \x01(\tH\x01\x12\x1e\n\x14token_constant_index\x18\x05 \x01(\x05H\x01\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42\x0c\n\ngate_valueB\x07\n\x05token\"\x12\n\x04Gate\x12\n\n\x02id\x18\x01 \x01(\t\"\x13\n\x05Qubit\x12\n\n\x02id\x18\x02 \x01(\t\"\x9c\x01\n\x03\x41rg\x12\x31\n\targ_value\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.ArgValueH\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x12\x18\n\x0e\x63onstant_index\x18\x04 \x01(\x05H\x00\x42\x05\n\x03\x61rg\"\xcf\x02\n\x08\x41rgValue\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12:\n\x0b\x62ool_values\x18\x02 \x01(\x0b\x32#.cirq.google.api.v2.RepeatedBooleanH\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x39\n\x0cint64_values\x18\x05 \x01(\x0b\x32!.cirq.google.api.v2.RepeatedInt64H\x00\x12;\n\rdouble_values\x18\x06 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedDoubleH\x00\x12;\n\rstring_values\x18\x07 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedStringH\x00\x42\x0b\n\targ_value\"\x1f\n\rRepeatedInt64\x12\x0e\n\x06values\x18\x01 \x03(\x03\" \n\x0eRepeatedDouble\x12\x0e\n\x06values\x18\x01 \x03(\x01\" \n\x0eRepeatedString\x12\x0e\n\x06values\x18\x01 \x03(\t\"!\n\x0fRepeatedBoolean\x12\x0e\n\x06values\x18\x01 \x03(\x08\"B\n\x0b\x41rgFunction\x12\x0c\n\x04type\x18\x01 \x01(\t\x12%\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xaf\x02\n\x10\x43ircuitOperation\x12\x1e\n\x16\x63ircuit_constant_index\x18\x01 \x01(\x05\x12M\n\x18repetition_specification\x18\x02 \x01(\x0b\x32+.cirq.google.api.v2.RepetitionSpecification\x12\x33\n\tqubit_map\x18\x03 \x01(\x0b\x32 .cirq.google.api.v2.QubitMapping\x12\x46\n\x13measurement_key_map\x18\x04 \x01(\x0b\x32).cirq.google.api.v2.MeasurementKeyMapping\x12/\n\x07\x61rg_map\x18\x05 \x01(\x0b\x32\x1e.cirq.google.api.v2.ArgMapping\"\xbc\x01\n\x17RepetitionSpecification\x12S\n\x0erepetition_ids\x18\x01 \x01(\x0b\x32\x39.cirq.google.api.v2.RepetitionSpecification.RepetitionIdsH\x00\x12\x1a\n\x10repetition_count\x18\x02 \x01(\x05H\x00\x1a\x1c\n\rRepetitionIds\x12\x0b\n\x03ids\x18\x01 \x03(\tB\x12\n\x10repetition_value\"\xac\x01\n\x0cQubitMapping\x12<\n\x07\x65ntries\x18\x01 \x03(\x0b\x32+.cirq.google.api.v2.QubitMapping.QubitEntry\x1a^\n\nQubitEntry\x12&\n\x03key\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\"$\n\x0eMeasurementKey\x12\x12\n\nstring_key\x18\x01 \x01(\t\"\xe2\x01\n\x15MeasurementKeyMapping\x12N\n\x07\x65ntries\x18\x01 \x03(\x0b\x32=.cirq.google.api.v2.MeasurementKeyMapping.MeasurementKeyEntry\x1ay\n\x13MeasurementKeyEntry\x12/\n\x03key\x18\x01 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\x12\x31\n\x05value\x18\x02 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\"\xa0\x01\n\nArgMapping\x12\x38\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\'.cirq.google.api.v2.ArgMapping.ArgEntry\x1aX\n\x08\x41rgEntry\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xcd\x01\n\x0cInternalGate\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x12\n\nnum_qubits\x18\x03 \x01(\x05\x12\x41\n\tgate_args\x18\x04 \x03(\x0b\x32..cirq.google.api.v2.InternalGate.GateArgsEntry\x1aH\n\rGateArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\"\xaf\x01\n\x0f\x43liffordTableau\x12\x17\n\nnum_qubits\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12\x1a\n\rinitial_state\x18\x02 \x01(\x05H\x01\x88\x01\x01\x12\x0f\n\x02rs\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x0f\n\x02xs\x18\x04 \x01(\x0cH\x03\x88\x01\x01\x12\x0f\n\x02zs\x18\x05 \x01(\x0cH\x04\x88\x01\x01\x42\r\n\x0b_num_qubitsB\x10\n\x0e_initial_stateB\x05\n\x03_rsB\x05\n\x03_xsB\x05\n\x03_zs\"O\n\x17SingleQubitCliffordGate\x12\x34\n\x07tableau\x18\x01 \x01(\x0b\x32#.cirq.google.api.v2.CliffordTableauB/\n\x1d\x63om.google.cirq.google.api.v2B\x0cProgramProtoP\x01\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -71,49 +71,53 @@ _globals['_WAITGATE']._serialized_start=1947 _globals['_WAITGATE']._serialized_end=2011 _globals['_OPERATION']._serialized_start=2014 - _globals['_OPERATION']._serialized_end=2951 - _globals['_OPERATION_ARGSENTRY']._serialized_start=2860 - _globals['_OPERATION_ARGSENTRY']._serialized_end=2928 - _globals['_GATE']._serialized_start=2953 - _globals['_GATE']._serialized_end=2971 - _globals['_QUBIT']._serialized_start=2973 - _globals['_QUBIT']._serialized_end=2992 - _globals['_ARG']._serialized_start=2995 - _globals['_ARG']._serialized_end=3151 - _globals['_ARGVALUE']._serialized_start=3154 - _globals['_ARGVALUE']._serialized_end=3489 - _globals['_REPEATEDINT64']._serialized_start=3491 - _globals['_REPEATEDINT64']._serialized_end=3522 - _globals['_REPEATEDDOUBLE']._serialized_start=3524 - _globals['_REPEATEDDOUBLE']._serialized_end=3556 - _globals['_REPEATEDSTRING']._serialized_start=3558 - _globals['_REPEATEDSTRING']._serialized_end=3590 - _globals['_REPEATEDBOOLEAN']._serialized_start=3592 - _globals['_REPEATEDBOOLEAN']._serialized_end=3625 - _globals['_ARGFUNCTION']._serialized_start=3627 - _globals['_ARGFUNCTION']._serialized_end=3693 - _globals['_CIRCUITOPERATION']._serialized_start=3696 - _globals['_CIRCUITOPERATION']._serialized_end=3999 - _globals['_REPETITIONSPECIFICATION']._serialized_start=4002 - _globals['_REPETITIONSPECIFICATION']._serialized_end=4190 - _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_start=4142 - _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_end=4170 - _globals['_QUBITMAPPING']._serialized_start=4193 - _globals['_QUBITMAPPING']._serialized_end=4365 - _globals['_QUBITMAPPING_QUBITENTRY']._serialized_start=4271 - _globals['_QUBITMAPPING_QUBITENTRY']._serialized_end=4365 - _globals['_MEASUREMENTKEY']._serialized_start=4367 - _globals['_MEASUREMENTKEY']._serialized_end=4403 - _globals['_MEASUREMENTKEYMAPPING']._serialized_start=4406 - _globals['_MEASUREMENTKEYMAPPING']._serialized_end=4632 - _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_start=4511 - _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_end=4632 - _globals['_ARGMAPPING']._serialized_start=4635 - _globals['_ARGMAPPING']._serialized_end=4795 - _globals['_ARGMAPPING_ARGENTRY']._serialized_start=4707 - _globals['_ARGMAPPING_ARGENTRY']._serialized_end=4795 - _globals['_INTERNALGATE']._serialized_start=4798 - _globals['_INTERNALGATE']._serialized_end=5003 - _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_start=4931 - _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_end=5003 + _globals['_OPERATION']._serialized_end=3031 + _globals['_OPERATION_ARGSENTRY']._serialized_start=2940 + _globals['_OPERATION_ARGSENTRY']._serialized_end=3008 + _globals['_GATE']._serialized_start=3033 + _globals['_GATE']._serialized_end=3051 + _globals['_QUBIT']._serialized_start=3053 + _globals['_QUBIT']._serialized_end=3072 + _globals['_ARG']._serialized_start=3075 + _globals['_ARG']._serialized_end=3231 + _globals['_ARGVALUE']._serialized_start=3234 + _globals['_ARGVALUE']._serialized_end=3569 + _globals['_REPEATEDINT64']._serialized_start=3571 + _globals['_REPEATEDINT64']._serialized_end=3602 + _globals['_REPEATEDDOUBLE']._serialized_start=3604 + _globals['_REPEATEDDOUBLE']._serialized_end=3636 + _globals['_REPEATEDSTRING']._serialized_start=3638 + _globals['_REPEATEDSTRING']._serialized_end=3670 + _globals['_REPEATEDBOOLEAN']._serialized_start=3672 + _globals['_REPEATEDBOOLEAN']._serialized_end=3705 + _globals['_ARGFUNCTION']._serialized_start=3707 + _globals['_ARGFUNCTION']._serialized_end=3773 + _globals['_CIRCUITOPERATION']._serialized_start=3776 + _globals['_CIRCUITOPERATION']._serialized_end=4079 + _globals['_REPETITIONSPECIFICATION']._serialized_start=4082 + _globals['_REPETITIONSPECIFICATION']._serialized_end=4270 + _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_start=4222 + _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_end=4250 + _globals['_QUBITMAPPING']._serialized_start=4273 + _globals['_QUBITMAPPING']._serialized_end=4445 + _globals['_QUBITMAPPING_QUBITENTRY']._serialized_start=4351 + _globals['_QUBITMAPPING_QUBITENTRY']._serialized_end=4445 + _globals['_MEASUREMENTKEY']._serialized_start=4447 + _globals['_MEASUREMENTKEY']._serialized_end=4483 + _globals['_MEASUREMENTKEYMAPPING']._serialized_start=4486 + _globals['_MEASUREMENTKEYMAPPING']._serialized_end=4712 + _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_start=4591 + _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_end=4712 + _globals['_ARGMAPPING']._serialized_start=4715 + _globals['_ARGMAPPING']._serialized_end=4875 + _globals['_ARGMAPPING_ARGENTRY']._serialized_start=4787 + _globals['_ARGMAPPING_ARGENTRY']._serialized_end=4875 + _globals['_INTERNALGATE']._serialized_start=4878 + _globals['_INTERNALGATE']._serialized_end=5083 + _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_start=5011 + _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_end=5083 + _globals['_CLIFFORDTABLEAU']._serialized_start=5086 + _globals['_CLIFFORDTABLEAU']._serialized_end=5261 + _globals['_SINGLEQUBITCLIFFORDGATE']._serialized_start=5263 + _globals['_SINGLEQUBITCLIFFORDGATE']._serialized_end=5342 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/program_pb2.pyi b/cirq-google/cirq_google/api/v2/program_pb2.pyi index aa688fabb77..289f9cfe5f0 100644 --- a/cirq-google/cirq_google/api/v2/program_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/program_pb2.pyi @@ -543,6 +543,7 @@ class Operation(google.protobuf.message.Message): MEASUREMENTGATE_FIELD_NUMBER: builtins.int WAITGATE_FIELD_NUMBER: builtins.int INTERNALGATE_FIELD_NUMBER: builtins.int + SINGLEQUBITCLIFFORDGATE_FIELD_NUMBER: builtins.int ARGS_FIELD_NUMBER: builtins.int QUBITS_FIELD_NUMBER: builtins.int QUBIT_CONSTANT_INDEX_FIELD_NUMBER: builtins.int @@ -576,6 +577,8 @@ class Operation(google.protobuf.message.Message): @property def internalgate(self) -> global___InternalGate: ... @property + def singlequbitcliffordgate(self) -> global___SingleQubitCliffordGate: ... + @property def args(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Arg]: """Map from the argument name to the Argument needed to fully specify the gate. Only populated pre-v2.5+. @@ -608,16 +611,17 @@ class Operation(google.protobuf.message.Message): measurementgate: global___MeasurementGate | None = ..., waitgate: global___WaitGate | None = ..., internalgate: global___InternalGate | None = ..., + singlequbitcliffordgate: global___SingleQubitCliffordGate | None = ..., args: collections.abc.Mapping[builtins.str, global___Arg] | None = ..., qubits: collections.abc.Iterable[global___Qubit] | None = ..., qubit_constant_index: collections.abc.Iterable[builtins.int] | None = ..., token_value: builtins.str = ..., token_constant_index: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["czpowgate", b"czpowgate", "fsimgate", b"fsimgate", "gate", b"gate", "gate_value", b"gate_value", "internalgate", b"internalgate", "iswappowgate", b"iswappowgate", "measurementgate", b"measurementgate", "phasedxpowgate", b"phasedxpowgate", "phasedxzgate", b"phasedxzgate", "token", b"token", "token_constant_index", b"token_constant_index", "token_value", b"token_value", "waitgate", b"waitgate", "xpowgate", b"xpowgate", "ypowgate", b"ypowgate", "zpowgate", b"zpowgate"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["args", b"args", "czpowgate", b"czpowgate", "fsimgate", b"fsimgate", "gate", b"gate", "gate_value", b"gate_value", "internalgate", b"internalgate", "iswappowgate", b"iswappowgate", "measurementgate", b"measurementgate", "phasedxpowgate", b"phasedxpowgate", "phasedxzgate", b"phasedxzgate", "qubit_constant_index", b"qubit_constant_index", "qubits", b"qubits", "token", b"token", "token_constant_index", b"token_constant_index", "token_value", b"token_value", "waitgate", b"waitgate", "xpowgate", b"xpowgate", "ypowgate", b"ypowgate", "zpowgate", b"zpowgate"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["czpowgate", b"czpowgate", "fsimgate", b"fsimgate", "gate", b"gate", "gate_value", b"gate_value", "internalgate", b"internalgate", "iswappowgate", b"iswappowgate", "measurementgate", b"measurementgate", "phasedxpowgate", b"phasedxpowgate", "phasedxzgate", b"phasedxzgate", "singlequbitcliffordgate", b"singlequbitcliffordgate", "token", b"token", "token_constant_index", b"token_constant_index", "token_value", b"token_value", "waitgate", b"waitgate", "xpowgate", b"xpowgate", "ypowgate", b"ypowgate", "zpowgate", b"zpowgate"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["args", b"args", "czpowgate", b"czpowgate", "fsimgate", b"fsimgate", "gate", b"gate", "gate_value", b"gate_value", "internalgate", b"internalgate", "iswappowgate", b"iswappowgate", "measurementgate", b"measurementgate", "phasedxpowgate", b"phasedxpowgate", "phasedxzgate", b"phasedxzgate", "qubit_constant_index", b"qubit_constant_index", "qubits", b"qubits", "singlequbitcliffordgate", b"singlequbitcliffordgate", "token", b"token", "token_constant_index", b"token_constant_index", "token_value", b"token_value", "waitgate", b"waitgate", "xpowgate", b"xpowgate", "ypowgate", b"ypowgate", "zpowgate", b"zpowgate"]) -> None: ... @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["gate_value", b"gate_value"]) -> typing_extensions.Literal["xpowgate", "ypowgate", "zpowgate", "phasedxpowgate", "phasedxzgate", "czpowgate", "fsimgate", "iswappowgate", "measurementgate", "waitgate", "internalgate"] | None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["gate_value", b"gate_value"]) -> typing_extensions.Literal["xpowgate", "ypowgate", "zpowgate", "phasedxpowgate", "phasedxzgate", "czpowgate", "fsimgate", "iswappowgate", "measurementgate", "waitgate", "internalgate", "singlequbitcliffordgate"] | None: ... @typing.overload def WhichOneof(self, oneof_group: typing_extensions.Literal["token", b"token"]) -> typing_extensions.Literal["token_value", "token_constant_index"] | None: ... @@ -1136,3 +1140,58 @@ class InternalGate(google.protobuf.message.Message): def ClearField(self, field_name: typing_extensions.Literal["gate_args", b"gate_args", "module", b"module", "name", b"name", "num_qubits", b"num_qubits"]) -> None: ... global___InternalGate = InternalGate + +@typing_extensions.final +class CliffordTableau(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NUM_QUBITS_FIELD_NUMBER: builtins.int + INITIAL_STATE_FIELD_NUMBER: builtins.int + RS_FIELD_NUMBER: builtins.int + XS_FIELD_NUMBER: builtins.int + ZS_FIELD_NUMBER: builtins.int + num_qubits: builtins.int + initial_state: builtins.int + rs: builtins.bytes + xs: builtins.bytes + zs: builtins.bytes + def __init__( + self, + *, + num_qubits: builtins.int | None = ..., + initial_state: builtins.int | None = ..., + rs: builtins.bytes | None = ..., + xs: builtins.bytes | None = ..., + zs: builtins.bytes | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["_initial_state", b"_initial_state", "_num_qubits", b"_num_qubits", "_rs", b"_rs", "_xs", b"_xs", "_zs", b"_zs", "initial_state", b"initial_state", "num_qubits", b"num_qubits", "rs", b"rs", "xs", b"xs", "zs", b"zs"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["_initial_state", b"_initial_state", "_num_qubits", b"_num_qubits", "_rs", b"_rs", "_xs", b"_xs", "_zs", b"_zs", "initial_state", b"initial_state", "num_qubits", b"num_qubits", "rs", b"rs", "xs", b"xs", "zs", b"zs"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_initial_state", b"_initial_state"]) -> typing_extensions.Literal["initial_state"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_num_qubits", b"_num_qubits"]) -> typing_extensions.Literal["num_qubits"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_rs", b"_rs"]) -> typing_extensions.Literal["rs"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_xs", b"_xs"]) -> typing_extensions.Literal["xs"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_zs", b"_zs"]) -> typing_extensions.Literal["zs"] | None: ... + +global___CliffordTableau = CliffordTableau + +@typing_extensions.final +class SingleQubitCliffordGate(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TABLEAU_FIELD_NUMBER: builtins.int + @property + def tableau(self) -> global___CliffordTableau: ... + def __init__( + self, + *, + tableau: global___CliffordTableau | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["tableau", b"tableau"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["tableau", b"tableau"]) -> None: ... + +global___SingleQubitCliffordGate = SingleQubitCliffordGate diff --git a/cirq-google/cirq_google/serialization/arg_func_langs.py b/cirq-google/cirq_google/serialization/arg_func_langs.py index 3e0b24ed4fc..735a93a8a97 100644 --- a/cirq-google/cirq_google/serialization/arg_func_langs.py +++ b/cirq-google/cirq_google/serialization/arg_func_langs.py @@ -19,6 +19,7 @@ import sympy from cirq_google.api import v2 from cirq_google.ops import InternalGate +from cirq.qis import CliffordTableau SUPPORTED_FUNCTIONS_FOR_LANGUAGE: Dict[Optional[str], FrozenSet[str]] = { '': frozenset(), @@ -455,3 +456,49 @@ def internal_gate_from_proto( num_qubits=int(msg.num_qubits), **gate_args, ) + + +def clifford_tableau_arg_to_proto( + value: CliffordTableau, *, out: Optional[v2.program_pb2.CliffordTableau] = None +): + """Writes an CliffordTableau object into an CliffordTableau proto. + + Args: + value: The gate to encode. + arg_function_language: The language to use when encoding functions. If + this is set to None, it will be set to the minimal language + necessary to support the features that were actually used. + out: The proto to write the result into. Defaults to a new instance. + + Returns: + The proto that was written into. + """ + msg = v2.program_pb2.CliffordTableau() if out is None else out + msg.num_qubits = value.n + msg.initial_state = value.initial_state + msg.xs = value.xs.tobytes() + msg.rs = value.rs.tobytes() + msg.zs = value.zs.tobytes() + return msg + + +def clifford_tableau_from_proto( + msg: v2.program_pb2.CliffordTableau, arg_function_language: str +) -> CliffordTableau: + """Extracts a CliffordTableau object from a CliffordTableau proto. + + Args: + msg: The proto containing a serialized value. + arg_function_language: The `arg_function_language` field from + `Program.Language`. + + Returns: + The deserialized InternalGate object. + """ + return CliffordTableau( + num_qubits=msg.num_qubits, + initial_state=msg.initial_state, + rs=np.frombuffer(msg.rs, dtype=bool) if msg.rs else None, + xs=np.frombuffer(msg.xs, dtype=bool).reshape((2 * msg.num_qubits, -1)) if msg.xs else None, + zs=np.frombuffer(msg.zs, dtype=bool).reshape((2 * msg.num_qubits, -1)) if msg.zs else None, + ) diff --git a/cirq-google/cirq_google/serialization/arg_func_langs_test.py b/cirq-google/cirq_google/serialization/arg_func_langs_test.py index b55edc53dc7..743a87ec71d 100644 --- a/cirq-google/cirq_google/serialization/arg_func_langs_test.py +++ b/cirq-google/cirq_google/serialization/arg_func_langs_test.py @@ -26,10 +26,13 @@ float_arg_to_proto, internal_gate_arg_to_proto, internal_gate_from_proto, + clifford_tableau_arg_to_proto, + clifford_tableau_from_proto, ARG_LIKE, LANGUAGE_ORDER, ) from cirq_google.api import v2 +from cirq.qis import CliffordTableau @pytest.mark.parametrize( @@ -249,3 +252,27 @@ def test_invalid_list(): with pytest.raises(ValueError): _ = arg_to_proto([1.0, '']) + + +@pytest.mark.parametrize('lang', LANGUAGE_ORDER) +def test_clifford_tableau(lang): + tests = [ + CliffordTableau( + 1, + 0, + rs=np.array([True, False], dtype=bool), + xs=np.array([[True], [False]], dtype=bool), + zs=np.array([[True], [False]], dtype=bool), + ), + CliffordTableau( + 1, + 1, + rs=np.array([True, True], dtype=bool), + xs=np.array([[True], [False]], dtype=bool), + zs=np.array([[False], [False]], dtype=bool), + ), + ] + for ct in tests: + proto = clifford_tableau_arg_to_proto(ct) + tableau = clifford_tableau_from_proto(proto, lang) + assert tableau == ct diff --git a/cirq-google/cirq_google/serialization/circuit_serializer.py b/cirq-google/cirq_google/serialization/circuit_serializer.py index 16fd0396755..db19e3e6a86 100644 --- a/cirq-google/cirq_google/serialization/circuit_serializer.py +++ b/cirq-google/cirq_google/serialization/circuit_serializer.py @@ -142,7 +142,11 @@ def _serialize_gate_op( """ gate = op.gate - if isinstance(gate, InternalGate): + if isinstance(gate, cirq.ops.SingleQubitCliffordGate): + arg_func_langs.clifford_tableau_arg_to_proto( + gate._clifford_tableau, out=msg.singlequbitcliffordgate.tableau + ) + elif isinstance(gate, InternalGate): arg_func_langs.internal_gate_arg_to_proto(gate, out=msg.internalgate) elif isinstance(gate, cirq.XPowGate): arg_func_langs.float_arg_to_proto( @@ -574,6 +578,12 @@ def _deserialize_gate_op( op = arg_func_langs.internal_gate_from_proto( operation_proto.internalgate, arg_function_language=arg_function_language )(*qubits) + elif which_gate_type == 'singlequbitcliffordgate': + tableau = arg_func_langs.clifford_tableau_from_proto( + operation_proto.singlequbitcliffordgate.tableau, + arg_function_language=arg_function_language, + ) + op = cirq.ops.SingleQubitCliffordGate.from_clifford_tableau(tableau)(*qubits) else: raise ValueError( f'Unsupported serialized gate with type "{which_gate_type}".' diff --git a/cirq-google/cirq_google/serialization/circuit_serializer_test.py b/cirq-google/cirq_google/serialization/circuit_serializer_test.py index 107bf70004a..8177c1ee5e2 100644 --- a/cirq-google/cirq_google/serialization/circuit_serializer_test.py +++ b/cirq-google/cirq_google/serialization/circuit_serializer_test.py @@ -256,6 +256,23 @@ def circuit_proto(json: Dict, qubits: List[str]): } ), ), + ( + cirq.ops.SingleQubitCliffordGate.X(Q0), + op_proto( + { + 'singlequbitcliffordgate': { + 'tableau': { + 'num_qubits': 1, + 'initial_state': 0, + 'rs': 'AAE=', + 'xs': 'AQA=', + 'zs': 'AAE=', + } + }, + 'qubit_constant_index': [0], + } + ), + ), ] @@ -668,3 +685,12 @@ def test_measurement_gate_deserialize() -> None: msg = cg.CIRCUIT_SERIALIZER.serialize(circuit) assert cg.CIRCUIT_SERIALIZER.deserialize(msg) == circuit + + +def test_circuit_with_cliffords(): + q = cirq.NamedQubit('q') + circuit = cirq.Circuit( + g(q) for g in cirq.ops.SingleQubitCliffordGate.all_single_qubit_cliffords + ) + msg = cg.CIRCUIT_SERIALIZER.serialize(circuit) + assert cg.CIRCUIT_SERIALIZER.deserialize(msg) == circuit