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

Allow measurement keys with differing qubits in OpenQASM #6803

Merged
merged 8 commits into from
Nov 22, 2024

Conversation

dstrain115
Copy link
Collaborator

  • Previously, if there was a measurement with the same key but two differently sized registers, then the qasm output might select the wrong key and size the register incorrectly.
  • This PR examines all the measurements first, and selects the biggest one, so to correctly size the classical register.
  • Adds unit test t demonstrate.

Fixes: #6508

- Previously, if there was a measurement with the same key
but two differently sized registers, then the qasm output
might select the wrong key and size the register incorrectly.
- This PR examines all the measurements first, and selects the
biggest one, so to correctly size the classical register.
- Adds unit test t demonstrate.

Fixes: quantumlib#6508
@dstrain115 dstrain115 requested review from vtomole and a team as code owners November 19, 2024 14:56
@CirqBot CirqBot added the size: S 10< lines changed <50 label Nov 19, 2024
Copy link

codecov bot commented Nov 19, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.85%. Comparing base (76125a2) to head (5a90191).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6803   +/-   ##
=======================================
  Coverage   97.85%   97.85%           
=======================================
  Files        1084     1084           
  Lines       93731    93742   +11     
=======================================
+ Hits        91722    91733   +11     
  Misses       2009     2009           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

@@ -289,22 +289,25 @@ def output(text):
output(f'qubit[{len(self.qubits)}] q;\n')
# Classical registers
# Pick an id for the creg that will store each measurement
already_output_keys: Set[str] = set()
# cregs will store key -> (#qubits, comment)
cregs: Dict[str, tuple[int, str]] = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

If you did this in the QasmOutput constructor and stored it in QasmArgs, you could pass it into KeyCondition.qasm, and fix #5691.

The reason it's required is that KeyCondition is triggered if meas[m_key] != 0. In OpenQasm2, the only logical comparator is equality, so != 0 can only be represented if the creg is a single bit (i.e. it would convert the condition to if m_key == 1). If the creg is multiple bits, then if m_key == 1 would be incorrect, and m_key != 0 is not representable. So that's why the existing behavior is to play it safe and just fail.

Going a little bit further, in OpenQasm3, it looks like m_key != 0 is representable, so checking QasmArgs.version in KeyCondition.qasm would allow supporting multi-bit classical controls if version == '3.0'. OpenQasm3 could also potentially support serializing additional types of logic in SympyConditions.

Copy link
Contributor

Choose a reason for hiding this comment

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

It might also be useful to have this be a function on Circuit or part of the measurement_keys protocol. I'd imagine "get the shapes of all the measurement keys in the circuit" would be a common need.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed to put into constructor, but I am not convinced that helps, since we don't pass QasmOutput during the qasm protocol. In any case, I will deal with classical controls in a follow-up PR.

Also, Circuit has enough cruft on it that I don't think it's a good idea to add more functions onto it, so I will leave it here.

Copy link
Collaborator

@pavoljuhas pavoljuhas left a comment

Choose a reason for hiding this comment

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

LGTM with an extra test for the 3.0 output.

cirq-core/cirq/circuits/qasm_output_test.py Outdated Show resolved Hide resolved
cirq-core/cirq/circuits/qasm_output_test.py Outdated Show resolved Hide resolved
cirq-core/cirq/circuits/qasm_output_test.py Show resolved Hide resolved
@@ -203,6 +203,7 @@ def __init__(
qubit_id_map=qubit_id_map,
meas_key_id_map=meas_key_id_map,
)
self.cregs = self._generate_cregs()
Copy link
Contributor

Choose a reason for hiding this comment

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

My suggestion from the earlier comment was to assign it to a field in self.args in the line above, since QasmArgs does get passed around. But that could be done as a separate PR for #5691. This lgtm for #6508.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, I see. That makes more sense. I will look into this in a follow-up PR.

@dstrain115 dstrain115 merged commit e0087b0 into quantumlib:main Nov 22, 2024
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: S 10< lines changed <50
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect Classical Register Size in to_qasm with Inhomogeneous Measurements
4 participants