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

Shot batching is made more efficient by executing all the shots in one go on Lightning Qubit #814

Merged
merged 8 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@

### Improvements

* Shot batching is made more efficient by executing all the shots in one go on LightningQubit.
[#814](https://github.com/PennyLaneAI/pennylane-lightning/pull/814)

* LightningQubit calls `generate_samples(wires)` on a minimal subset of wires when executing in finite-shot mode.
[(#813)](https://github.com/PennyLaneAI/pennylane-lightning/pull/813)

* Avoid unnecessary memory reset in LightningQubit's state vector class constructor.
[(#811)](https://github.com/PennyLaneAI/pennylane-lightning/pull/811)

* Add `generate_samples(wires)` support in LightningQubit.
[(#809)](https://github.com/PennyLaneAI/pennylane-lightning/pull/809)

* Optimize the OpenMP parallelization of Lightning-Qubit's `probs` for all number of targets.
[(#807)](https://github.com/PennyLaneAI/pennylane-lightning/pull/807)

Expand Down Expand Up @@ -71,7 +74,7 @@

This release contains contributions from (in alphabetical order):

Amintor Dusko, Vincent Michaud-Rioux, Shuli Shu
Ali Asadi, Amintor Dusko, Vincent Michaud-Rioux, Shuli Shu

---

Expand Down
2 changes: 1 addition & 1 deletion pennylane_lightning/core/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.38.0-dev16"
__version__ = "0.38.0-dev17"
36 changes: 10 additions & 26 deletions pennylane_lightning/lightning_qubit/_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,31 +401,6 @@

return tuple(processed)

# if there is a shot vector, build a list containing results for each shot entry
if shots.has_partitioned_shots:
processed_samples = []
for s in shots:
# currently we call sample_state for each shot entry, but it may be
# better to call sample_state just once with total_shots, then use
# the shot_range keyword argument
try:
if self._mcmc:
samples = self._measurement_lightning.generate_mcmc_samples(
len(wires), self._kernel_name, self._num_burnin, s
).astype(int, copy=False)
else:
samples = self._measurement_lightning.generate_samples(
maliasadi marked this conversation as resolved.
Show resolved Hide resolved
list(wires), s
).astype(int, copy=False)
except ValueError as e:
if str(e) != "probabilities contain NaN":
raise e
samples = qml.math.full((s, len(wires)), 0)

processed_samples.append(_process_single_shot(samples))
self._apply_diagonalizing_gates(mps, adjoint=True)
return tuple(zip(*processed_samples))

try:
if self._mcmc:
samples = self._measurement_lightning.generate_mcmc_samples(
Expand All @@ -442,7 +417,16 @@

self._apply_diagonalizing_gates(mps, adjoint=True)

return _process_single_shot(samples)
# if there is a shot vector, use the shots.bins generator to
# split samples w.r.t. the shots
processed_samples = []
for lower, upper in shots.bins():
result = _process_single_shot(samples[..., lower:upper, :])
processed_samples.append(result)

Check warning on line 425 in pennylane_lightning/lightning_qubit/_measurements.py

View check run for this annotation

Codecov / codecov/patch

pennylane_lightning/lightning_qubit/_measurements.py#L422-L425

Added lines #L422 - L425 were not covered by tests

return (

Check warning on line 427 in pennylane_lightning/lightning_qubit/_measurements.py

View check run for this annotation

Codecov / codecov/patch

pennylane_lightning/lightning_qubit/_measurements.py#L427

Added line #L427 was not covered by tests
maliasadi marked this conversation as resolved.
Show resolved Hide resolved
tuple(zip(*processed_samples)) if shots.has_partitioned_shots else processed_samples[0]
)

def _measure_hamiltonian_with_samples(
self,
Expand Down
23 changes: 22 additions & 1 deletion tests/test_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from conftest import LightningDevice as ld
from conftest import device_name, lightning_ops, validate_measurements
from flaky import flaky
from pennylane.measurements import Expectation, Variance
from pennylane.measurements import Expectation, Shots, Variance

if not ld._CPP_BINARY_AVAILABLE:
pytest.skip("No binary module found. Skipping.", allow_module_level=True)
Expand Down Expand Up @@ -828,3 +828,24 @@ def func(x, y):
results2 = func2(*params)

validate_measurements(measure_f, shots, results1, results2)


# TODO: Add LT after extending the support for shots_vector
@pytest.mark.skipif(
device_name == "lightning.tensor",
reason="lightning.tensor does not support shot vectors.",
)
@pytest.mark.parametrize("shots", ((1, 10), (1, 10, 100), (1, 10, 10, 100, 100, 100)))
def test_shots_bins(shots, qubit_device):
"""Tests that Lightning handles multiple shots."""

dev = qubit_device(wires=1, shots=shots)

@qml.qnode(dev)
def circuit():
return qml.expval(qml.PauliZ(wires=0))

if dev.name == "lightning.qubit":
assert np.sum(shots) == circuit.device.shots.total_shots

assert np.allclose(circuit(), 1.0)
Loading