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

Retain ordering information in conversion. #4384

Merged
merged 25 commits into from
Jan 6, 2022

Conversation

Cynocracy
Copy link
Contributor

Previously, when you requested a cirq result with measurement A, and B, we would return a Result object that contained the correct counts for A and B, but which eliminated any correlation information we had (by throwing the results order out in count()). This changes so that count() is derived from another method, ordered_results, which takes a key and returns the list of list of bit-wise results in a consistent way from key to key.

@google-cla
Copy link

google-cla bot commented Aug 4, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added the cla: no label Aug 4, 2021
@google-cla
Copy link

google-cla bot commented Aug 4, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@Cynocracy
Copy link
Contributor Author

@googlebot I signed it!

@ColemanCollins
Copy link
Collaborator

ColemanCollins commented Aug 4, 2021

will actually play with this and such later, but just for posterity while I'm thinking about it, the specific repro case that this is addressing (that I brought to Jon's attention on a different channel) is reconstructing multiple measurement keys into a histogram, i.e.

import cirq
import numpy as np
import interface as interface
import sympy
qubit=cirq.LineQubit.range(2)
theta=np.pi
circuit=cirq.Circuit()
circuit.append(interface.h(qubit[0]))
circuit.append(interface.h(qubit[1]))
for i in range(5):
    circuit.append(interface.cnot(qubit[0],qubit[1]))
    circuit.append(cirq.rz(sympy.Symbol('phi')).on(qubit[1]))
    circuit.append(interface.cnot(qubit[0],qubit[1]))
circuit.append(interface.h(qubit[0]))
circuit.append(interface.h(qubit[1]))
resolved=cirq.resolve_parameters(circuit,{"phi":1.5/18*np.pi})
for i in range(len(resolved.all_qubits())):
    resolved.append(cirq.measure(cirq.LineQubit(i)))
job=service.create_job(circuit=resolved,repetitions=1000,target="qpu")
job.results().to_cirq_result().multi_measurement_histogram(keys=["0","1"])

v.s. a simple

job.results().counts()

or creating a histogram from a measurement key that included both qubits to begin with:

    resolved.append(cirq.measure(qubit[0], qubit[1], key="both"))
    job=service.create_job(circuit=resolved,repetitions=1000,target="qpu")
    job.results().to_cirq_result().histogram(key="both")

these should theoretically all be the same, but because we don't preserve measurement correlation when building via counts(key) and simple list comprehension, we lose this information, which causes the first example to produce different composite counts than the latter two.

Yes, in both cases we're faking the real measurement list (i.e. the IonQ API doesn't actually give us an ordered list of individual measurements) but at least this way we're faking it in a way that behaves better with Cirq's assumptions about that list

@google-cla google-cla bot added cla: yes Makes googlebot stop complaining. and removed cla: no labels Aug 4, 2021
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.

A small test case would be very useful for analyzing this change :)

@@ -39,8 +40,40 @@ def repetitions(self) -> int:
"""Returns the number of times the circuit was run."""
return self._repetitions

def ordered_results(self, key: Optional[str] = None) -> List[List[int]]:
""" Returns a list of arbitrarily but consistently orderd results.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nits
typo: ordered
also extra space

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

@@ -26,7 +26,8 @@ class QPUResult:
def __init__(
self, counts: Dict[int, int], num_qubits: int, measurement_dict: Dict[str, Sequence[int]]
):
self._counts = counts
# Guaranteed iter ordering is required for conversion to Cirq results.
self._counts = collections.OrderedDict(counts)
Copy link
Collaborator

Choose a reason for hiding this comment

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

If feels strange to me that this is taking a dict, which has no ordering constraints, and then converting it to an ordered dict. I think if the ordering is necessary, shouldn't the counts parameter have that contract?

Copy link
Collaborator

Choose a reason for hiding this comment

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

note that python 3.6 dicts are insertion ordered in cpython, but this is an implementation detail. in 3.7 this becomes the standard. So since Cirq still supports 3.6 we need to use OrderedDict.

I think you want to move the OrderedDict up to the Job results 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.

Changed this to be more explicit that we're sorting here by bitvector to get ordering. WDYT?

@dabacon
Copy link
Collaborator

dabacon commented Aug 9, 2021

Here is a test case that shows the problem

counts = collections.OrderedDict()
counts[0b00] = 10
counts[0b01] = 10
result1 = ionq.QPUResult(counts, num_qubits=2, measurement_dict={'a': [0], 'b': [1]})

counts = collections.OrderedDict()
counts[0b01] = 10
counts[0b00] = 10
result2 = ionq.QPUResult(counts, num_qubits=2, measurement_dict={'a': [0], 'b': [1]})

assert result1.to_cirq_result() == result2.to_cirq_result()

@Cynocracy
Copy link
Contributor Author

test case added, I took a slightly different tack than you did, lmk what you think :)

@Cynocracy Cynocracy changed the title [wip] Retain ordering information in conversion. Retain ordering information in conversion. Aug 9, 2021
@Cynocracy Cynocracy requested a review from dabacon August 9, 2021 18:27
@Cynocracy
Copy link
Contributor Author

Updated some type and formatting that the tests didn't like.

@CirqBot CirqBot added size: XL lines changed >1000 size: M 50< lines changed <250 and removed size: XL lines changed >1000 labels Aug 12, 2021
@google-cla
Copy link

google-cla bot commented Sep 7, 2021

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added cla: no and removed cla: yes Makes googlebot stop complaining. labels Sep 7, 2021
@CirqBot CirqBot removed the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Nov 23, 2021
@dabacon
Copy link
Collaborator

dabacon commented Nov 23, 2021

Looks like you have format errors. run check/format-incremental --apply

This should also fix lint.

Looks like you also hit a flakey test, investigating.

@Cynocracy
Copy link
Contributor Author

Aye aye! No worries re: radar, thanks for circling back :)

@Cynocracy Cynocracy requested a review from wcourtney as a code owner December 1, 2021 17:34
@Cynocracy
Copy link
Contributor Author

@dabacon friendly ping (been a while since I've pinged the likes of you :) !)

@ColemanCollins ColemanCollins added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Jan 6, 2022
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Jan 6, 2022
@CirqBot CirqBot merged commit c1389ce into quantumlib:master Jan 6, 2022
@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 Jan 6, 2022
@ColemanCollins
Copy link
Collaborator

ColemanCollins commented Jan 6, 2022

adding the automerge tag back for Jon now that the format errors are fixed and tests are passing and such because he doesn't have the perms to do it himself. Feel free to revert if this feels out of line

@Cynocracy Cynocracy deleted the patch-2 branch January 6, 2022 22:46
MichaelBroughton pushed a commit to MichaelBroughton/Cirq that referenced this pull request Jan 22, 2022
Previously, when you requested a cirq result with measurement A, and B, we would return a Result object that contained the correct counts for A and B, but which eliminated any correlation information we had (by throwing the results order out in count()). This changes so that count() is derived from another method, ordered_results, which takes a key and returns the list of list of bit-wise results in a consistent way from key to key.
rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
Previously, when you requested a cirq result with measurement A, and B, we would return a Result object that contained the correct counts for A and B, but which eliminated any correlation information we had (by throwing the results order out in count()). This changes so that count() is derived from another method, ordered_results, which takes a key and returns the list of list of bit-wise results in a consistent way from key to key.
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: M 50< lines changed <250
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants