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

Qcut sampling postprocessing function #2358

Merged
merged 51 commits into from
Mar 29, 2022

Conversation

anthayes92
Copy link
Contributor

Context:
The pipeline for cutting a circuit with sampling measurements requires it own postprocessing capabilities. This will support returning bitstrings as well as expectation values, the choice of which should be specified by the user.

Description of the Change:
Add sampling postprocessing function

Benefits:
Facilitates cutting circuits with sampling measurements

Possible Drawbacks:
Potential computational bottleneck depending on number of fragments circuits to be processed

anthayes92 and others added 30 commits March 11, 2022 18:51
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
…ithub.com:PennyLaneAI/pennylane into qcut-sample-subgraphs-to-fragment-tape-conversion
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Copy link
Contributor

@trbromley trbromley left a comment

Choose a reason for hiding this comment

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

Thanks @anthayes92!

doc/releases/changelog-dev.md Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
Comment on lines 1998 to 1999
for pp, exp_pp in zip(postprocessed, expected_postprocessed):
assert np.allclose(pp, exp_pp)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
for pp, exp_pp in zip(postprocessed, expected_postprocessed):
assert np.allclose(pp, exp_pp)
assert np.allclose(postprocessed[0], expected_postprocessed[0])

Do we need the loop if there's only one element?

gives the correct results.
"""

def test_sample_postprocess(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be good to have an interface-based test like here, where we also check that the returned is converted to the right interface type.

for pp, exp_pp in zip(postprocessed, expected_postprocessed):
assert np.allclose(pp, exp_pp)

def test_mc_sample_postprocess(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly for this test, would be good to check for all the interfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These tests now iterate over all interfaces.

tests/transforms/test_qcut.py Show resolved Hide resolved
fixed_samples, communication_graph, fixed_settings, shots, func
)

expected = 85.33333333333333
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be tempted to add some spy functionality (e.g., to classical_processing_fn,prod, and potentially hstack) to check the provided inputs are as expected.

pennylane/transforms/qcut.py Show resolved Hide resolved
pennylane/transforms/qcut.py Show resolved Hide resolved

fixed_settings = np.array([[0, 7, 1], [5, 7, 2], [1, 0, 3], [5, 1, 1]])

# spy_func = mocker.spy(fn)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure how to spy on this function, generally we use mocker.spy(package, "function") but this function exists by itself so I only have a single arg to pass to spy

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, can leave out for now 👍

Copy link
Contributor

@trbromley trbromley left a comment

Choose a reason for hiding this comment

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

Thanks @anthayes92! Just left a few more comments - would it also be possible to fix what is mentioned here?

pennylane/transforms/qcut.py Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
]

postprocessed = qcut.qcut_processing_fn_sample(fixed_samples, communication_graph, shots)
postprocessed = qml.math.cast_like(postprocessed, lib.ones(1))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we casting the output to the interface type? We need to cast the input to the interface type and check that the output is of the same type.

Copy link
Contributor

Choose a reason for hiding this comment

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

(same for the test below)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah I got mixed up! changed here: fd328ac


fixed_settings = np.array([[0, 7, 1], [5, 7, 2], [1, 0, 3], [5, 1, 1]])

# spy_func = mocker.spy(fn)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, can leave out for now 👍

tests/transforms/test_qcut.py Show resolved Hide resolved
anthayes92 and others added 2 commits March 25, 2022 09:38
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
@anthayes92
Copy link
Contributor Author

Thanks for the suggestions @trbromley , I've updated the docsting for expand_fragment_tapes_mc to include the settings array and also changed the tape diagrams since the tape.draw() function has been updated to give cleaner output.

Copy link
Contributor

@trbromley trbromley left a comment

Choose a reason for hiding this comment

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

Thanks @anthayes92. I've left a final round of comments but should be good to merge once resolved.

doc/releases/changelog-dev.md Outdated Show resolved Hide resolved
doc/releases/changelog-dev.md Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Show resolved Hide resolved
pennylane/transforms/qcut.py Outdated Show resolved Hide resolved
pennylane/transforms/qcut.py Show resolved Hide resolved
np.array([[0.0], [-1.0], [-1.0]]),
np.array([[1.0], [1.0], [1.0]]),
]
cast_fixed_samples = [qml.math.cast_like(fs, lib.ones(1)) for fs in fixed_samples]
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
cast_fixed_samples = [qml.math.cast_like(fs, lib.ones(1)) for fs in fixed_samples]
cast_fixed_samples = [qml.math.convert_like(fs, lib.ones(1)) for fs in fixed_samples]

This is an important distinction.

Comment on lines 2015 to 2017
fragment_configurations, settings = qml.transforms.qcut.expand_fragment_tapes_mc(
fragment_tapes, communication_graph, shots
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fragment_configurations, settings = qml.transforms.qcut.expand_fragment_tapes_mc(
fragment_tapes, communication_graph, shots
)

np.array([[0.0], [-1.0], [-1.0]]),
np.array([[1.0], [1.0], [1.0]]),
]
cast_fixed_samples = [qml.math.cast_like(fs, lib.ones(1)) for fs in fixed_samples]
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
cast_fixed_samples = [qml.math.cast_like(fs, lib.ones(1)) for fs in fixed_samples]
cast_fixed_samples = [qml.math.convert_like(fs, lib.ones(1)) for fs in fixed_samples]

postprocessed = qcut.qcut_processing_fn_mc(
fixed_samples, communication_graph, fixed_settings, shots, fn
)
postprocessed = qml.math.cast_like(postprocessed, lib.ones(1))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
postprocessed = qml.math.cast_like(postprocessed, lib.ones(1))

I don't think we need this - we should be testing that postprocessed is the expected type without casting.

spy_hstack = mocker.spy(np, "hstack")

postprocessed = qcut.qcut_processing_fn_mc(
fixed_samples, communication_graph, fixed_settings, shots, fn
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fixed_samples, communication_graph, fixed_settings, shots, fn
cast_fixed_samples, communication_graph, fixed_settings, shots, fn

@anthayes92
Copy link
Contributor Author

Thanks for the suggestions @trbromley . Updates to the tests have been manually checked and added here: ceb1383

anthayes92 and others added 2 commits March 28, 2022 09:55
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Copy link
Contributor

@trbromley trbromley left a comment

Choose a reason for hiding this comment

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

Thanks @anthayes92!

@anthayes92 anthayes92 merged commit 62afe04 into master Mar 29, 2022
@anthayes92 anthayes92 deleted the qcut-sampling-postprocessing-function branch March 29, 2022 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants