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

Insertion noise model #4672

Merged
merged 10 commits into from
Dec 14, 2021
Merged

Conversation

95-martin-orion
Copy link
Collaborator

This PR is part of #4640. It adds the InsertionNoiseModel, which injects noise based on a user-defined map.

#4671 is a prerequisite for this PR. The only files that need to be reviewed in this PR are:

  • cirq-core/cirq/devices/...
    • __init__.py
    • insertion_noise_model[_test].py

@95-martin-orion 95-martin-orion requested review from cduck, vtomole and a team as code owners November 12, 2021 18:05
@CirqBot CirqBot added the size: L 250< lines changed <1000 label Nov 12, 2021
@google-cla google-cla bot added the cla: yes Makes googlebot stop complaining. label Nov 12, 2021
@MichaelBroughton MichaelBroughton self-assigned this Nov 12, 2021
Comment on lines 51 to 71
noise_ops: List['cirq.Operation'] = []
for op in moment:
if self.require_physical_tag and PHYSICAL_GATE_TAG not in op.tags:
# Only non-virtual gates get noise applied.
continue
op_id = OpIdentifier(type(op.gate), *op.qubits)
if op_id in self.ops_added:
noise_ops.append(self.ops_added[op_id])
continue
# Find the closest match, if one exists.
parent_id = OpIdentifier(object, *op.qubits)
for added_id in self.ops_added:
if added_id.qubits != parent_id.qubits:
continue
if not issubclass(op_id.gate_type, added_id.gate_type):
continue
if issubclass(added_id.gate_type, parent_id.gate_type):
parent_id = added_id
if parent_id.gate_type != object:
noise_ops.append(self.ops_added[parent_id])
if not noise_ops:
return [moment]
if self.prepend:
return [ops.Moment(noise_ops), moment]
return [moment, ops.Moment(noise_ops)]
Copy link
Collaborator

@MichaelBroughton MichaelBroughton Nov 12, 2021

Choose a reason for hiding this comment

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

This is pretty hard to read. Also, the object-like containment check that falls back to type-like containment check is something gatesets can do for you. Also if there are gates or operations in self.ops_added with overlapping parent types this might have uh-intuitive behavior for the user. Could we tighten this up a bit ?
Maybe something along the lines of:

non_virtual_ops = [op if self.require_physical_tag and PHYSICAL_GATE_TAG not in op.tags for op in moment]
mappings = self.ops_added.items()
converted_ops = [v(*op.qubits) for k,v in mappings for op in non_virtual_ops if op in k]
return converted_ops + moment

where self.ops_added maps from gatesets to operations ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

cirq.Gateset is not serializable, which causes complications when interacting with NoiseProperties. It's likely possible to get this working, but I expect it to be more complicated than the current behavior.

RE overlapping parent types: this is addressed here and covered in tests. If you have something like:

class A: {...}
class B(A): {...}
class C(B): {...}

ops_added = {
    OpIdentifier(A, q0): cirq.X(q0),
    OpIdentifier(B, q0): cirq.Z(q0),
}

then objects of type B or C will generate cirq.Z(q0) as noise, and objects of type A will produce cirq.X(q0) as noise.

Copy link
Collaborator

Choose a reason for hiding this comment

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

cirq.Gateset is not serializable, which causes complications when interacting with NoiseProperties

Can this be fixed easily @tanujkhattar ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Discussed offline. @95-martin-orion will try to replace the existing logic with gate families and gatesets. I will add 2 new features to gatesets

  • A method that can return the matched gate family instead of just returning true/false while checking for containment
  • If all gate families of a Gateset are serializable, then the gateset should be serializable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Discussed out-of-band with @tanujkhattar - I can reconstruct this to use Gatesets and GateFamilys with a fairly low attached cost. I'll probably need to rehash these PRs again to support that, but until then I'm happy to take any other comments you have, since the remaining structure of this change should remain similar.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changes have been applied to #4671, and will be added here soon. PTAL

@95-martin-orion
Copy link
Collaborator Author

Updated with the new OpIdentifier match tools. Pinging @MichaelBroughton for review.

Copy link
Collaborator

@MichaelBroughton MichaelBroughton left a comment

Choose a reason for hiding this comment

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

LGTM after some nits

cirq-core/cirq/devices/insertion_noise_model.py Outdated Show resolved Hide resolved
cirq-core/cirq/devices/insertion_noise_model.py Outdated Show resolved Hide resolved
cirq-core/cirq/devices/insertion_noise_model.py Outdated Show resolved Hide resolved

def noisy_moment(
self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']
) -> 'cirq.OP_TREE':
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Docstring.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This defines the noisy_moment method of the parent class and inherits its docstring. Compare with noisy_moments in ConstantQubitNoiseModel.

@95-martin-orion 95-martin-orion added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Dec 14, 2021
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Dec 14, 2021
@CirqBot CirqBot merged commit 807a24d into quantumlib:master Dec 14, 2021
@CirqBot CirqBot removed automerge Tells CirqBot to sync and merge this PR. (If it's running.) front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. labels Dec 14, 2021
MichaelBroughton pushed a commit to MichaelBroughton/Cirq that referenced this pull request Jan 22, 2022
This PR is part of quantumlib#4640. It adds the `InsertionNoiseModel`, which injects noise based on a user-defined map.

quantumlib#4671 is a prerequisite for this PR. The only files that need to be reviewed in this PR are:

- `cirq-core/cirq/devices/...`
    - `__init__.py`
    - `insertion_noise_model[_test].py`
rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
This PR is part of quantumlib#4640. It adds the `InsertionNoiseModel`, which injects noise based on a user-defined map.

quantumlib#4671 is a prerequisite for this PR. The only files that need to be reviewed in this PR are:

- `cirq-core/cirq/devices/...`
    - `__init__.py`
    - `insertion_noise_model[_test].py`
harry-phasecraft pushed a commit to PhaseCraft/Cirq that referenced this pull request Oct 31, 2024
This PR is part of quantumlib#4640. It adds the `InsertionNoiseModel`, which injects noise based on a user-defined map.

quantumlib#4671 is a prerequisite for this PR. The only files that need to be reviewed in this PR are:

- `cirq-core/cirq/devices/...`
    - `__init__.py`
    - `insertion_noise_model[_test].py`
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. size: L 250< lines changed <1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants