Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add act_on protocol #3019

Merged
merged 8 commits into from
May 20, 2020
Merged

Add act_on protocol #3019

merged 8 commits into from
May 20, 2020

Conversation

Strilanc
Copy link
Contributor

  • Add act_on_protocol.py
  • Add act_on to MeasurementGate and ResetChannel
  • Add ActOnStateVectorArgs to represent state vector simulator state
  • Move logic out of sparse_simulator.py and into ActOnStateVectorArgs._fallback_act_on
  • Fix ApplyUnitaryArgs.subspace_index not forwarding shape information
  • Add allow_decompose to several protocol methods
  • Fix CliffordSimulator accepting measurements that may not be stabilizers
  • Fix _verify_unique_measurement_keys not using measurement_keys
  • Add test that terminal measurement simulations can have random results
  • with_gate now returns self if new_gate is gate
  • GateOperation now delegates protocols directly to its gate when possible

- Add act_on_protocol.py
- Add _act_on_ to MeasurementGate and ResetChannel
- Add ActOnStateVectorArgs to represent state vector simulator state
- Move logic out of sparse_simulator.py and into ActOnStateVectorArgs._fallback_act_on
- Fix ApplyUnitaryArgs.subspace_index not forwarding shape information
- Add allow_decompose to several protocol methods
- Fix CliffordSimulator accepting measurements that may not be stabilizers
- Fix _verify_unique_measurement_keys not using measurement_key**s**
- Add test that terminal measurement simulations can have random results
- with_gate now returns self if new_gate is gate
- GateOperation now delegates protocols directly to its gate when possible
@googlebot googlebot added the cla: yes Makes googlebot stop complaining. label May 18, 2020
Copy link
Collaborator

@dabacon dabacon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The amount of code this cleans up in the sparse simulator makes me think this is a great pattern. A few comments.

cirq/protocols/act_on_protocol.py Outdated Show resolved Hide resolved
cirq/protocols/act_on_protocol.py Show resolved Hide resolved
@@ -114,33 +116,57 @@ def _decompose_(self) -> 'cirq.OP_TREE':
NotImplemented)

def _pauli_expansion_(self) -> value.LinearDict[str]:
return protocols.pauli_expansion(self.gate)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the advantage of delegating in these methods? I don't see why this is better and adds a lot of boilerplate getattr code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. The triggering event for me is that the allow_decompose parameter was not being respected in several places when GateOperation was in play. For example, has_unitary(gate_op, allow_decompose=True) would call GateOperation._has_unitary_, which would call has_unitary(gate) with no allow_decompose=True, resulting in the decomposition being computed.

Basically, if we bounce a protocol method back into itself then we can get an amplification effect where more work than necessary is done because fallback logic is run once per bounce-back-level. By delegating directly into the implementation of the sub gate, fallback logic is only run once. This makes things more efficient, and honestly a bit more stable or at least predictable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well about decompose :). We should probably make this the norm then throughout.

cirq/ops/measurement_gate.py Show resolved Hide resolved
cirq/protocols/apply_unitary_protocol.py Show resolved Hide resolved
expected to perform inplace edits of this object.
available_buffer: A workspace with the same shape and dtype as
`target_tensor`. The result of an operation can be put into this
buffer, instead of directly editing `target_tensor`, if
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might reword this because it's a bit hard to parse. I think what you are saying is that if the result is put into the avaliable buffer instead of acting on inline, then swap_target_tensor_for should be called to put this in target_tensor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

def __init__(self, target_tensor: np.ndarray, available_buffer: np.ndarray,
axes: Iterable[int], prng: np.random.RandomState,
log_of_measurement_results: Dict[str, Any]):
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably useful to describe the different use cases, inline, using a buffer, and creating a new vector?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

cirq/sim/act_on_state_vector_args.py Show resolved Hide resolved
bit of the integer is the desired bit for the first axis, and
so forth in decreasing order. Can't be specified at the same
time as `little_endian_bits_int`.
value_tuple: The desired value of the qids at the targeted `axes`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this parameter doesn't exist in this method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

cirq/sim/clifford/clifford_simulator.py Show resolved Hide resolved
@Strilanc Strilanc added the Ready for Re-Review For when reviewers take their time. label May 20, 2020
@Strilanc Strilanc added automerge Tells CirqBot to sync and merge this PR. (If it's running.) and removed Ready for Re-Review For when reviewers take their time. labels May 20, 2020
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label May 20, 2020
@CirqBot CirqBot merged commit a344fb7 into master May 20, 2020
@CirqBot CirqBot removed the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label May 20, 2020
@CirqBot CirqBot deleted the act_on branch May 20, 2020 16:52
@CirqBot CirqBot removed the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label May 20, 2020
tonybruguier pushed a commit to tonybruguier/Cirq that referenced this pull request Aug 23, 2020
- Add act_on_protocol.py
- Add _act_on_ to MeasurementGate and ResetChannel
- Add ActOnStateVectorArgs to represent state vector simulator state
- Move logic out of sparse_simulator.py and into ActOnStateVectorArgs._fallback_act_on
- Fix ApplyUnitaryArgs.subspace_index not forwarding shape information
- Add allow_decompose to several protocol methods
- Fix CliffordSimulator accepting measurements that may not be stabilizers
- Fix _verify_unique_measurement_keys not using measurement_key**s**
- Add test that terminal measurement simulations can have random results
- with_gate now returns self if new_gate is gate
- GateOperation now delegates protocols directly to its gate when possible
CirqBot pushed a commit that referenced this pull request Mar 17, 2021
Fixes #3825

Sparse and Clifford simulators both have a proper ActOnXXXStateArgs where simulator state is maintained and acted upon by various operations. This was first added in #3019 with the act_on protocol.

DensityMatrix and MPS simulators were never updated with the new protocol, leaving the codebase inconsistent and the migration unfinished. This PR finishes the task for DensityMatrix. A separate PR for MPS simulator hopefully will follow.

Aditionally, this PR introduces an `ActOnArgs` base class to eliminate the code duplication and type checking that was required in `MeasurementGate` (it had grown to four `if isinstance` blocks, each with duplicate bitshift/logging code), and replace it all with a single function call back into the `args` object.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Makes googlebot stop complaining.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants