Skip to content

Commit

Permalink
Enable CircuitOp serialization. (#4344)
Browse files Browse the repository at this point in the history
This PR adds `CircuitOperation` serializers to the default gateset used in QCS. After it is submitted, `CircuitOperation`s sent to QCS will be serialized in a compact format, reducing the size of highly-repetitive circuits.

Not included in this PR:
* Support for `CircuitOperation`s in `cirq.optimized_for_sycamore` (to be added in #4336)
  • Loading branch information
95-martin-orion committed Jul 21, 2021
1 parent 055db68 commit 4d956c5
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cirq-google/cirq_google/devices/known_devices_test.py
Expand Up @@ -102,6 +102,9 @@ def test_foxtail_device_proto():
gate_duration_picos: 4000000
valid_targets: "meas_targets"
}
valid_gates {
id: "circuit"
}
}
valid_qubits: "0_0"
valid_qubits: "0_1"
Expand Down Expand Up @@ -389,6 +392,9 @@ def test_multiple_gate_sets():
gate_duration_picos: 14141
valid_targets: "meas_targets"
}
valid_gates {
id: "circuit"
}
}
valid_gate_sets {
name: "half_pi_gateset"
Expand Down
12 changes: 12 additions & 0 deletions cirq-google/cirq_google/gate_sets.py
Expand Up @@ -33,6 +33,8 @@
COUPLER_PULSE_DESERIALIZER,
WAIT_GATE_SERIALIZER,
WAIT_GATE_DESERIALIZER,
CIRCUIT_OP_SERIALIZER,
CIRCUIT_OP_DESERIALIZER,
)

SYC_GATESET = serializable_gate_set.SerializableGateSet(
Expand All @@ -43,13 +45,15 @@
*SINGLE_QUBIT_HALF_PI_SERIALIZERS,
MEASUREMENT_SERIALIZER,
WAIT_GATE_SERIALIZER,
CIRCUIT_OP_SERIALIZER,
],
deserializers=[
SYC_DESERIALIZER,
*SINGLE_QUBIT_DESERIALIZERS,
*SINGLE_QUBIT_HALF_PI_DESERIALIZERS,
MEASUREMENT_DESERIALIZER,
WAIT_GATE_DESERIALIZER,
CIRCUIT_OP_DESERIALIZER,
],
)
document(SYC_GATESET, """Gate set with fsim(pi/2, pi/6) as the core 2 qubit interaction.""")
Expand All @@ -61,12 +65,14 @@
*SINGLE_QUBIT_SERIALIZERS,
MEASUREMENT_SERIALIZER,
WAIT_GATE_SERIALIZER,
CIRCUIT_OP_SERIALIZER,
],
deserializers=[
*SQRT_ISWAP_DESERIALIZERS,
*SINGLE_QUBIT_DESERIALIZERS,
MEASUREMENT_DESERIALIZER,
WAIT_GATE_DESERIALIZER,
CIRCUIT_OP_DESERIALIZER,
],
)
document(SQRT_ISWAP_GATESET, """Gate set with sqrt(iswap) as the core 2 qubit interaction.""")
Expand All @@ -79,12 +85,14 @@
*SINGLE_QUBIT_SERIALIZERS,
MEASUREMENT_SERIALIZER,
WAIT_GATE_SERIALIZER,
CIRCUIT_OP_SERIALIZER,
],
deserializers=[
LIMITED_FSIM_DESERIALIZER,
*SINGLE_QUBIT_DESERIALIZERS,
MEASUREMENT_DESERIALIZER,
WAIT_GATE_DESERIALIZER,
CIRCUIT_OP_DESERIALIZER,
],
)
document(FSIM_GATESET, """Gate set that combines sqrt(iswap) and syc as one fsim id.""")
Expand All @@ -98,13 +106,15 @@
*SINGLE_QUBIT_SERIALIZERS,
MEASUREMENT_SERIALIZER,
WAIT_GATE_SERIALIZER,
CIRCUIT_OP_SERIALIZER,
],
deserializers=[
COUPLER_PULSE_DESERIALIZER,
LIMITED_FSIM_DESERIALIZER,
*SINGLE_QUBIT_DESERIALIZERS,
MEASUREMENT_DESERIALIZER,
WAIT_GATE_DESERIALIZER,
CIRCUIT_OP_DESERIALIZER,
],
)
document(
Expand All @@ -120,11 +130,13 @@
*SINGLE_QUBIT_SERIALIZERS,
CZ_POW_SERIALIZER,
MEASUREMENT_SERIALIZER,
CIRCUIT_OP_SERIALIZER,
],
deserializers=[
*SINGLE_QUBIT_DESERIALIZERS,
CZ_POW_DESERIALIZER,
MEASUREMENT_DESERIALIZER,
CIRCUIT_OP_DESERIALIZER,
],
)
document(XMON, """Gate set for XMON devices.""")
Expand Down
47 changes: 47 additions & 0 deletions cirq-google/cirq_google/gate_sets_test.py
Expand Up @@ -527,3 +527,50 @@ def test_serialize_deserialize_wait_gate():
assert cg.SYC_GATESET.deserialize_op(proto) == op
assert cg.SQRT_ISWAP_GATESET.serialize_op(op) == proto
assert cg.SQRT_ISWAP_GATESET.deserialize_op(proto) == op


def default_circuit_proto():
op1 = v2.program_pb2.Operation()
op1.gate.id = 'x_pow'
op1.args['half_turns'].arg_value.string_value = 'k'
op1.qubits.add().id = '1_1'

return v2.program_pb2.Circuit(
scheduling_strategy=v2.program_pb2.Circuit.MOMENT_BY_MOMENT,
moments=[
v2.program_pb2.Moment(
operations=[op1],
),
],
)


def default_circuit():
return cirq.FrozenCircuit(
cirq.X(cirq.GridQubit(1, 1)) ** sympy.Symbol('k'),
cirq.measure(cirq.GridQubit(1, 1), key='m'),
)


@pytest.mark.parametrize('gateset', [cg.XMON, cg.SYC_GATESET, cg.SQRT_ISWAP_GATESET])
def test_serialize_deserialize_circuit_op(gateset):
circuit_op = cirq.CircuitOperation(default_circuit())
proto = v2.program_pb2.CircuitOperation()
proto.circuit_constant_index = 0
proto.repetition_specification.repetition_count = 1

constants = [default_circuit_proto()]
raw_constants = {default_circuit(): 0}
assert (
gateset.serialize_op(circuit_op, constants=constants, raw_constants=raw_constants) == proto
)

constants = [default_circuit_proto()]
deserialized_constants = [default_circuit()]

assert (
gateset.deserialize_op(
proto, constants=constants, deserialized_constants=deserialized_constants
)
== circuit_op
)

0 comments on commit 4d956c5

Please sign in to comment.