Repository navigation
Conversation
| @@ -870,7 +875,9 @@ def serialize_circuit(circuit_inp): | |||
| ] | |||
There was a problem hiding this comment.
Possible additional performance improvement: if a moment does not have a controlled operation, a new Moment many not need to be created to replace it later below on lines 885-886. So, the following might be worth adding:
| ] | |
| ] | |
| if not controlled_ops: | |
| continue |
There was a problem hiding this comment.
Might be worth adding to test_serialize_does_not_tag_input_circuit:
In addition to asserting self.assertFalse(hasattr(sub_op, '_tfq_control_qubits')) and self.assertFalse(hasattr(sub_op, '_tfq_control_values')), serializing cirq.Circuit(sub_op) afterward and asserting that
proto.circuit.moments[0].operations[0].args['control_qubits'].arg_value.string_value == ''will verify observable serialization output even if internal attribute names change in the future.
There was a problem hiding this comment.
An additional point: the existing test checks hasattr(sub_op, '_tfq_control_qubits'). That catches the exact leak this PR guards against. But it is tied to a private attribute name, and it doesn't show why a leak matters. The real hazard: if a tagged sub-operation object is reused somewhere else uncontrolled, it later serializes as a controlled gate. That changes simulation results silently.
|
@adlantz Thank you for the benchmarks in the PR description. Could you also attach the benchmark script? |
Issue #336 asks for improvements to the
tfq.convert_to_tensor speedfunction. The majorirty of the run time occurs in the cirq serialization logic:Inspecting
serialize_circuitI noticed a quick win would be to not do a full deep copy of the input circuit, instead create a shallow copy withcircuit = circuit_inp.copy(). The risk with this is that we may modify the input circuit (change in behavior). We can get away with this because moments are replaces rather than edited in place by the serializer, i.eThat being said, in the controlled operations demotion loop, we reference and mutate
op.sub_operationwhich points to an attribute on the input circuit. Therefore, we make a copy there of each sub operation.Overall the speedup is significant:
The downside is less peace of mind that the input circuit is not mutated, and any changes here in the future need to keep that in mind.
I added a test to ensure serialization does not mutate the input circuit.