Skip to content

Commit c82198b

Browse files
authored
Migrate lightning.qubit to the new API (#646)
* fix reset state * Update pennylane_lightning/lightning_qubit/_state_vector.py * Update pennylane_lightning/lightning_qubit/_state_vector.py * Update pennylane_lightning/lightning_qubit/_state_vector.py * remove LightningQubit2 references * remove unnecessary modules * merging Serializer classes * update serialize tests * update measurements with new serialize class * remove outdated test * register with setup.py, state vector fixes * remove obsolete tests * remove unused dtype input from simulate * update measurements * update state_vector * update lightning_qubit2 * format * pylint * Update pennylane_lightning/lightning_qubit/_state_vector.py * remove old comment * some review suggestions * Auto update version * remove print * update state vector class * add state vector class tests * adding measurement tests * update state vector and tests * move and rename test files, and format * Auto update version * skip measurements class for other devices and in the absence of binaries * format * add LightningQubit2 to init and format * update measurements class * expand measurement class testing * garbage collection * typo * update coverage and StateVector class * expand measurements class coverage * Auto update version * add coverage for n-controlled operations * add map to standard wires to get_final_state for safety * update jax config import * Auto update version * trigger CI * update state vector class and tests for improved coverage * update measurement class tests * update dev version * add cpp binary available variable * remove device definition * update dev version * Auto update version * reduce dependency on DefaultQubit for tests * update LightningQubit2 * clean test_measurements_class.py * isort+black * review suggestion * fix docs * Add qml.var support. * Add probs support. * increase tolerance * Auto update version * isort * Add double-obs tests. * Pin pytest version (#624) * update dev version * update changelog * pin pytest version in requirement files * add a requirements file for tests against Pennylane master * update wheels' workflows * Version Bump (#626) * post release version bump * increase tolerance * Introduce isort. (#623) * Introduce isort. * Auto update version * Update changelog * Auto update version * Update changelog. * trigger ci * Auto update version * isort * Add qml.var support. * Add probs support. * Add measurement tests with wires. * review suggestions * remove unused imports * Introduce _new_API and fix/skip few tests. * Fix few more tests. * Skip shots, adjoint, vjp with new API. * remove diagonalization gate application from state vector * pytest.skip tests * Auto update version * Fix format * Fix no-bin interface. * WIP * Initial shots support + fix test_measurement tests. * update * adding tests from add-simulate branch * merge conflicts * create state vector on initialization * remove import of modifier from lightning * Update pennylane_lightning/lightning_qubit/lightning_qubit2.py * minor test updates * register with setup.py, state vector fixes * add LightningQubit2 to init and format * add cpp binary available variable * reduce dependency on DefaultQubit for tests * update LightningQubit2 * Fixing rebase artifacts * Add fewLQ2 tests. * remove adjoint diff support from supports derivatives * Remove print from test_apply * Add expval/var tests. * Remove duplicate class data. * Include LQ2 in linux tests. * Add _group_measurements support. * --cov-append * Add mcmc capability + tests. * Auto update version * update dev version * add LightningAdjointJacobian class * add unit tests for the LightningAdjointJacobian class * format * add changelog for PR #613 * [skip ci] Added skeleton file for LQ2 unit tests * update changelog * update adjoint Jacobian * Auto update version * codefactor * Add shots tests and fix bugs in LQ, LQ2. * Lightning qubit2 upgrade api (#628) * update * adding tests from add-simulate branch * merge conflicts * create state vector on initialization * remove import of modifier from lightning * Update pennylane_lightning/lightning_qubit/lightning_qubit2.py * minor test updates * register with setup.py, state vector fixes * add LightningQubit2 to init and format * add cpp binary available variable * Auto update version * reduce dependency on DefaultQubit for tests * update LightningQubit2 * Introduce _new_API and fix/skip few tests. * Fix few more tests. * Skip shots, adjoint, vjp with new API. * Fix no-bin interface. * Remove duplicate class data. * Include LQ2 in linux ests. * --cov-append * fix processing_fn_expval * make a proper new_tape * Added init tests; Added skeleton tests for helpers * Fix more bug with shots. * trigger CI * Change pennylane branch for CI. * Update .github/CHANGELOG.md * Update pennylane_lightning/lightning_qubit/_adjoint_jacobian.py * Update pennylane_lightning/lightning_qubit/_adjoint_jacobian.py * Add probs support. * Add double-obs tests. * Add qml.var support. * Add probs support. * Add measurement tests with wires. * pytest.skip tests * Fix format * update * adding tests from add-simulate branch * merge conflicts * create state vector on initialization * remove import of modifier from lightning * Update pennylane_lightning/lightning_qubit/lightning_qubit2.py * minor test updates * register with setup.py, state vector fixes * add LightningQubit2 to init and format * add cpp binary available variable * reduce dependency on DefaultQubit for tests * update LightningQubit2 * Fixing rebase artifacts * remove adjoint diff support from supports derivatives * [skip ci] Added skeleton file for LQ2 unit tests * Lightning qubit2 upgrade api (#628) * update * adding tests from add-simulate branch * merge conflicts * create state vector on initialization * remove import of modifier from lightning * Update pennylane_lightning/lightning_qubit/lightning_qubit2.py * minor test updates * register with setup.py, state vector fixes * add LightningQubit2 to init and format * add cpp binary available variable * Auto update version * reduce dependency on DefaultQubit for tests * update LightningQubit2 * Introduce _new_API and fix/skip few tests. * Fix few more tests. * Skip shots, adjoint, vjp with new API. * Fix no-bin interface. * Remove duplicate class data. * Include LQ2 in linux ests. * --cov-append * Added init tests; Added skeleton tests for helpers * Resolving rebase artifacts * Refactor shots test. * Added tests; integrated jacobian * Update pennylane_lightning/lightning_qubit/lightning_qubit2.py * Auto update version * Small update to simulate_and_jacobian * Auto update version * Rerun isort. * Uncomment integration tests. * Reformat * Delete symlink * Fix pylint. * Run linux tests in parallel (when possible). * Run double obs tests with shots. * Revert linux tests * Fix bg in diag_gates. * Call isort/black with python -m * update dev version * Add docstrings, rm C_DTYPE. * Auto update version * comment isort check * trigger ci * Update tests/test_expval.py * Init mcmc params to None in measurements. * Reformat with python3.11 * Reformat black * Auto update version * update QuantumScriptSerializer * remove LightningQubit2 from init * update setup.py * remove lightning.qubit2 from tests configuration * remove extra tests for lightning.qubit2 * migrate lightning.qubit2 to lightning.qubit on tests * make lightning.qubit2 the new lightning.qubit * add device name (necessary for pl-device-test) * Add _measure_hamiltonian_with_samples _measure_sum_with_samples * fix tests without binary * check for jac size before reshaping * remove obsolete tests * organize tests * fix test for Windows wheels * fix the fix for LightningKokkos * undo 'fix' * trigger CI * update changelog * Auto update version * commenting tests for Win wheels * trigger build wheels
1 parent 21cc89f commit c82198b

23 files changed

+453
-1332
lines changed

.github/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
### Breaking changes
2525

26+
* Migrate `lightning.qubit` to the new device API.
27+
[(#646)](https://github.com/PennyLaneAI/pennylane-lightning/pull/646)
28+
2629
* Introduce `ci:build_wheels` label, which controls wheel building on `pull_request` and other triggers.
2730
[(#648)](https://github.com/PennyLaneAI/pennylane-lightning/pull/648)
2831

.github/workflows/tests_linux.yml

-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ jobs:
185185
cd main/
186186
DEVICENAME=`echo ${{ matrix.pl_backend }} | sed "s/_/./g"`
187187
PL_DEVICE=${DEVICENAME} python -m pytest tests/ $COVERAGE_FLAGS
188-
PL_DEVICE=lightning_qubit2 python -m pytest tests/ $COVERAGE_FLAGS --cov-append
189188
pl-device-test --device ${DEVICENAME} --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
190189
pl-device-test --device ${DEVICENAME} --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
191190
mv .coverage .coverage-${{ github.job }}-${{ matrix.pl_backend }}

.github/workflows/tests_without_binary.yml

-3
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,6 @@ jobs:
107107
cd main/
108108
DEVICENAME=`echo ${{ matrix.pl_backend }} | sed "s/_/./g"`
109109
PL_DEVICE=${DEVICENAME} python -m pytest tests/ $COVERAGE_FLAGS
110-
if [ ${{ matrix.pl_backend }} == "lightning_qubit" ]; then PL_DEVICE=lightning_qubit2 python -m pytest tests/ $COVERAGE_FLAGS --cov-append; fi
111-
pl-device-test --device ${DEVICENAME} --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
112-
pl-device-test --device ${DEVICENAME} --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
113110
114111
- name: Upload coverage to Codecov
115112
uses: codecov/codecov-action@v3

.github/workflows/wheel_win_x86_64.yml

+5-4
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,12 @@ jobs:
127127
CIBW_BEFORE_BUILD: |
128128
python -m pip install pybind11 cmake~=3.24.0 build
129129
130-
CIBW_BEFORE_TEST: |
131-
python -m pip install -r requirements-tests.txt
130+
#Temporarily commenting while solving problems to find binaries in CIBW tests.
131+
# CIBW_BEFORE_TEST: |
132+
# python -m pip install -r requirements-tests.txt
132133

133-
CIBW_TEST_COMMAND: |
134-
pl-device-test --device=lightning.qubit --skip-ops -x --tb=short --no-flaky-report
134+
# CIBW_TEST_COMMAND: |
135+
# pl-device-test --device=lightning.qubit --skip-ops -x --tb=short --no-flaky-report
135136

136137
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
137138

pennylane_lightning/core/_serialize.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def __init__(
6262
self.use_csingle = use_csingle
6363
self.device_name = device_name
6464
self.split_obs = split_obs
65-
if device_name in ("lightning.qubit", "lightning.qubit2"):
65+
if device_name == "lightning.qubit":
6666
try:
6767
import pennylane_lightning.lightning_qubit_ops as lightning_ops
6868
except ImportError as exception:

pennylane_lightning/core/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
Version number (major.minor.patch[-label])
1717
"""
1818

19-
__version__ = "0.36.0-dev13"
19+
__version__ = "0.36.0-dev14"

pennylane_lightning/lightning_qubit/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@
1616
from pennylane_lightning.core import __version__
1717

1818
from .lightning_qubit import LightningQubit
19-
from .lightning_qubit2 import LightningQubit2

pennylane_lightning/lightning_qubit/_adjoint_jacobian.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ def calculate_jacobian(self, tape: QuantumTape):
243243
trainable_params,
244244
)
245245
jac = np.array(jac)
246-
jac = jac.reshape(-1, len(trainable_params))
246+
jac = jac.reshape(-1, len(trainable_params)) if len(jac) else jac
247247
jac_r = np.zeros((jac.shape[0], processed_data["all_params"]))
248248
jac_r[:, processed_data["record_tp_rows"]] = jac
249249

pennylane_lightning/lightning_qubit/_measurements.py

+51-8
Original file line numberDiff line numberDiff line change
@@ -320,18 +320,21 @@ def measure_with_samples(
320320
if isinstance(group[0], (ExpectationMP, VarianceMP)) and isinstance(
321321
group[0].obs, SparseHamiltonian
322322
):
323-
raise TypeError("ExpectationMP(SparseHamiltonian) cannot be computed with samples.")
324-
if isinstance(group[0], (ExpectationMP, VarianceMP)) and isinstance(
325-
group[0].obs, Hamiltonian
326-
):
327-
raise TypeError("ExpectationMP(Hamiltonian) cannot be computed with samples.")
328-
if isinstance(group[0], (ExpectationMP, VarianceMP)) and isinstance(group[0].obs, Sum):
329-
raise TypeError("ExpectationMP(Sum) cannot be computed with samples.")
323+
raise TypeError(
324+
"ExpectationMP/VarianceMP(SparseHamiltonian) cannot be computed with samples."
325+
)
326+
if isinstance(group[0], VarianceMP) and isinstance(group[0].obs, (Hamiltonian, Sum)):
327+
raise TypeError("VarianceMP(Hamiltonian/Sum) cannot be computed with samples.")
330328
if isinstance(group[0], (ClassicalShadowMP, ShadowExpvalMP)):
331329
raise TypeError(
332330
"ExpectationMP(ClassicalShadowMP, ShadowExpvalMP) cannot be computed with samples."
333331
)
334-
all_res.extend(self._measure_with_samples_diagonalizing_gates(group, shots))
332+
if isinstance(group[0], ExpectationMP) and isinstance(group[0].obs, Hamiltonian):
333+
all_res.extend(self._measure_hamiltonian_with_samples(group, shots))
334+
elif isinstance(group[0], ExpectationMP) and isinstance(group[0].obs, Sum):
335+
all_res.extend(self._measure_sum_with_samples(group, shots))
336+
else:
337+
all_res.extend(self._measure_with_samples_diagonalizing_gates(group, shots))
335338

336339
# reorder results
337340
flat_indices = []
@@ -438,3 +441,43 @@ def _process_single_shot(samples):
438441
self._apply_diagonalizing_gates(mps, adjoint=True)
439442

440443
return _process_single_shot(samples)
444+
445+
def _measure_hamiltonian_with_samples(
446+
self,
447+
mp: List[SampleMeasurement],
448+
shots: Shots,
449+
):
450+
# the list contains only one element based on how we group measurements
451+
mp = mp[0]
452+
453+
# if the measurement process involves a Hamiltonian, measure each
454+
# of the terms separately and sum
455+
def _sum_for_single_shot(s):
456+
results = self.measure_with_samples(
457+
[ExpectationMP(t) for t in mp.obs.terms()[1]],
458+
s,
459+
)
460+
return sum(c * res for c, res in zip(mp.obs.terms()[0], results))
461+
462+
unsqueezed_results = tuple(_sum_for_single_shot(type(shots)(s)) for s in shots)
463+
return [unsqueezed_results] if shots.has_partitioned_shots else [unsqueezed_results[0]]
464+
465+
def _measure_sum_with_samples(
466+
self,
467+
mp: List[SampleMeasurement],
468+
shots: Shots,
469+
):
470+
# the list contains only one element based on how we group measurements
471+
mp = mp[0]
472+
473+
# if the measurement process involves a Sum, measure each
474+
# of the terms separately and sum
475+
def _sum_for_single_shot(s):
476+
results = self.measure_with_samples(
477+
[ExpectationMP(t) for t in mp.obs],
478+
s,
479+
)
480+
return sum(results)
481+
482+
unsqueezed_results = tuple(_sum_for_single_shot(type(shots)(s)) for s in shots)
483+
return [unsqueezed_results] if shots.has_partitioned_shots else [unsqueezed_results[0]]

0 commit comments

Comments
 (0)