Skip to content

Commit 60551b4

Browse files
authored
Partial support of reset gate in cirq_google protos (#7095)
* Remove arg_function_language - We have no need for this parameter and it is pretty much always set to the most permissive parameter. - Removes this parameter to simplify serialization. * Fix some typecheck stuff. * Fix test * Address comments. * Partial support of reset gate in cirq_google protos - This change adds reset gate to the list of gates and adds a default deserialization to cirq.ResetChannel. - Other internal hardware reset mechanisms are not yet supported, and will be added later using custom deserializers. * Address comments.
1 parent 09432f6 commit 60551b4

File tree

5 files changed

+189
-85
lines changed

5 files changed

+189
-85
lines changed

cirq-google/cirq_google/api/v2/program.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ message Operation {
246246
IdentityGate identitygate = 19;
247247
HPowGate hpowgate = 20;
248248
SingleQubitCliffordGate singlequbitcliffordgate = 21;
249+
ResetGate resetgate = 24;
249250
}
250251

251252
// Map from the argument name to the Argument needed to fully specify
@@ -617,3 +618,14 @@ message IdentityGate {
617618
message HPowGate {
618619
FloatArg exponent = 1;
619620
}
621+
622+
message ResetGate {
623+
// Type of reset to be executed (hardware dependent)
624+
// Internal users should use the name of the class.
625+
// (Note that this is not used for public-facing circuits,
626+
// which will default to cirq.ResetChannel)
627+
string reset_type = 1;
628+
629+
// Additional arguments that can be sent to the reset implementation.
630+
map<string, Arg> arguments = 2;
631+
}

cirq-google/cirq_google/api/v2/program_pb2.py

Lines changed: 88 additions & 82 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cirq-google/cirq_google/api/v2/program_pb2.pyi

Lines changed: 51 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cirq-google/cirq_google/serialization/circuit_serializer.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ def _serialize_gate_op(
237237
arg_func_langs.float_arg_to_proto(
238238
gate.duration.total_nanos(), out=msg.waitgate.duration_nanos
239239
)
240+
elif isinstance(gate, cirq.ResetChannel):
241+
arg_func_langs.arg_to_proto(gate.dimension, out=msg.resetgate.arguments['dimension'])
240242
elif isinstance(gate, CouplerPulse):
241243
arg_func_langs.float_arg_to_proto(
242244
gate.hold_time.total_picos(), out=msg.couplerpulsegate.hold_time_ps
@@ -648,6 +650,14 @@ def _deserialize_gate_op(
648650
operation_proto.waitgate.duration_nanos, required_arg_name=None
649651
)
650652
op = cirq.WaitGate(duration=cirq.Duration(nanos=total_nanos or 0.0))(*qubits)
653+
elif which_gate_type == 'resetgate':
654+
dimensions = arg_func_langs.arg_from_proto(
655+
operation_proto.resetgate.arguments.get('dimension', 2)
656+
)
657+
if not isinstance(dimensions, int):
658+
# This should always be int, if serialized from cirq.
659+
raise ValueError(f"dimensions {dimensions} for ResetChannel must be an integer!")
660+
op = cirq.ResetChannel(dimension=dimensions)(*qubits)
651661
elif which_gate_type == 'internalgate':
652662
op = arg_func_langs.internal_gate_from_proto(operation_proto.internalgate)(*qubits)
653663
elif which_gate_type == 'couplerpulsegate':

cirq-google/cirq_google/serialization/circuit_serializer_test.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,15 @@ def circuit_proto(json: Dict, qubits: List[str]):
263263
{'waitgate': {'duration_nanos': {'float_value': 15}}, 'qubit_constant_index': [0]}
264264
),
265265
),
266+
(
267+
cirq.R(Q0),
268+
op_proto(
269+
{
270+
'resetgate': {'arguments': {'dimension': {'arg_value': {'float_value': 2}}}},
271+
'qubit_constant_index': [0],
272+
}
273+
),
274+
),
266275
(
267276
cirq.MeasurementGate(num_qubits=2, key='iron', invert_mask=(True, False))(Q0, Q1),
268277
op_proto(
@@ -1006,3 +1015,22 @@ def test_custom_serializer(use_constants_table: bool):
10061015
assert isinstance(op.gate, BingBongGate)
10071016
assert op.gate.param == 2.5
10081017
assert op.qubits == (cirq.q(0, 0),)
1018+
1019+
1020+
def test_reset_gate_with_improper_argument():
1021+
serializer = cg.CircuitSerializer()
1022+
1023+
op = v2.program_pb2.Operation()
1024+
op.resetgate.arguments['dimension'].arg_value.float_value = 2.5
1025+
op.qubit_constant_index.append(0)
1026+
circuit_proto = v2.program_pb2.Program(
1027+
language=v2.program_pb2.Language(arg_function_language='exp', gate_set=_SERIALIZER_NAME),
1028+
circuit=v2.program_pb2.Circuit(
1029+
scheduling_strategy=v2.program_pb2.Circuit.MOMENT_BY_MOMENT,
1030+
moments=[v2.program_pb2.Moment(operations=[op])],
1031+
),
1032+
constants=[v2.program_pb2.Constant(qubit=v2.program_pb2.Qubit(id='1_2'))],
1033+
)
1034+
1035+
with pytest.raises(ValueError, match="must be an integer"):
1036+
serializer.deserialize(circuit_proto)

0 commit comments

Comments
 (0)