Skip to content

Commit

Permalink
Add support for LinearCombination (#649)
Browse files Browse the repository at this point in the history
* 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

* trigger CI

---------

Co-authored-by: AmintorDusko <[email protected]>
Co-authored-by: AmintorDusko <[email protected]>

* increase tolerance

* Introduce isort. (#623)

* Introduce isort.

* Auto update version

* Update changelog

* Auto update version

* Update changelog.

* trigger ci

---------

Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com>

* 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 ests.

* 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

---------

Co-authored-by: albi3ro <[email protected]>
Co-authored-by: AmintorDusko <[email protected]>
Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com>

* 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

Co-authored-by: Vincent Michaud-Rioux <[email protected]>

* Update pennylane_lightning/lightning_qubit/_adjoint_jacobian.py

Co-authored-by: Vincent Michaud-Rioux <[email protected]>

* Update pennylane_lightning/lightning_qubit/_adjoint_jacobian.py

Co-authored-by: Vincent Michaud-Rioux <[email protected]>

* 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

---------

Co-authored-by: albi3ro <[email protected]>
Co-authored-by: AmintorDusko <[email protected]>
Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com>

* 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

Co-authored-by: Amintor Dusko <[email protected]>

* 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

Co-authored-by: Amintor Dusko <[email protected]>

* 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

* Adding LC to supported obs list for all devices

* Updating serialization

* Trying out test changes

* Updated PL dependency

* Running isort

* Update CPP layer for observable accessible functions

* Auto update version

* Allow output from  TP CPP layer

* Fixed serialize tests

* Added legacy fixture to failing tests

* Updated requirements with debug branch

* Trigger CI

* Auto update version

* Trigger CI

* Trigger CI

* Added recursive logic to find projectors

* format

* mark tests to be dual tested and some small fixes

* example of test failing

* remove print and move ham to tape scope

* Fixed expval test; isort

* Auto update version

* isort

* Updated device tests; changelog entry

* Update mpitests/test_apply.py

* Auto update version

* Fix terms in ham serialization.

* Use requirements-dev.txt to install black/isort.

* Mark test_single_return_value flaky. Add comment on split_obs.

* Apply suggestions from code review

Co-authored-by: Ali Asadi <[email protected]>
Co-authored-by: Vincent Michaud-Rioux <[email protected]>

* Auto update version

* Auto update version

* Trigger CI

* Fix format

* Updated PL branch in reqs-dev

* Update requirements

* Added fix for prod with overlapping wires

* Formatting

* Point requirements to PL master

* Pinning cmake

* Pinned cmake in workflows

* Pinned cmake in more workflows

* Trigger CI

* Apply suggestions from code review

Co-authored-by: Ali Asadi <[email protected]>

* [skip ci] Apply suggestions from code review

Co-authored-by: Ali Asadi <[email protected]>

* Trigger CI

* Fix indent.

* Fix workflow files indentation

* Comment triggers. (#662)

* Comment triggers.

* pytest -x

* trigger ci

* Do not skip comp for LQ.

* Revert triggers

* Revert changes

---------

Co-authored-by: AmintorDusko <[email protected]>
Co-authored-by: Amintor Dusko <[email protected]>
Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Vincent Michaud-Rioux <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: AmintorDusko <[email protected]>
Co-authored-by: Vincent Michaud-Rioux <[email protected]>
Co-authored-by: albi3ro <[email protected]>
Co-authored-by: Lee J. O'Riordan <[email protected]>
Co-authored-by: Ali Asadi <[email protected]>
Co-authored-by: Lee James O'Riordan <[email protected]>
  • Loading branch information
12 people authored Mar 27, 2024
1 parent 7e77c5d commit 044ffe8
Show file tree
Hide file tree
Showing 24 changed files with 413 additions and 199 deletions.
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
[(#607)](https://github.com/PennyLaneAI/pennylane-lightning/pull/607)
[(#628)](https://github.com/PennyLaneAI/pennylane-lightning/pull/628)

* Add support for using new operator arithmetic as the default.
[(#649)](https://github.com/PennyLaneAI/pennylane-lightning/pull/649)

### Breaking changes

* Migrate `lightning.qubit` to the new device API.
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/tests_gpu_cuda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ jobs:
- name: Install required packages
run: |
python -m pip install ninja cmake custatevec-cu${{ matrix.cuda_version }}
# Omitting the installation of cmake v3.29.0 due to
# https://github.com/scikit-build/cmake-python-distributions/pull/474
python -m pip install ninja "cmake!=3.29.0" custatevec-cu${{ matrix.cuda_version }}
sudo apt-get -y -q install liblapack-dev
- name: Build and run unit tests
Expand Down Expand Up @@ -241,7 +243,9 @@ jobs:
run: |
cd main
python -m pip install -r requirements-dev.txt
python -m pip install cmake custatevec-cu${{ matrix.cuda_version }} openfermionpyscf
# Omitting the installation of cmake v3.29.0 due to
# https://github.com/scikit-build/cmake-python-distributions/pull/474
python -m pip install "cmake!=3.29.0" custatevec-cu${{ matrix.cuda_version }} openfermionpyscf
- name: Checkout PennyLane for release build
if: inputs.pennylane-version == 'release'
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/tests_linux_x86_mpi_gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ jobs:
- name: Install required packages
run: |
python -m pip install -r requirements-dev.txt
python -m pip install cmake custatevec-cu12
# Omitting the installation of cmake v3.29.0 due to
# https://github.com/scikit-build/cmake-python-distributions/pull/474
python -m pip install "cmake!=3.29.0" custatevec-cu12
sudo apt-get -y -q install liblapack-dev
- name: Validate GPU version and installed compiler and modules
Expand Down Expand Up @@ -240,7 +242,7 @@ jobs:
source /etc/profile.d/modules.sh && module use /opt/modules/ && module load ${{ matrix.mpilib }}/cuda-${{ matrix.cuda_version_maj }}.${{ matrix.cuda_version_min }}
python -m pip install -r requirements-dev.txt
python -m pip install custatevec-cu${{ matrix.cuda_version_maj }} mpi4py openfermionpyscf
SKIP_COMPILATION=True PL_BACKEND=lightning_qubit python -m pip install -e . -vv
PL_BACKEND=lightning_qubit python -m pip install -e . -vv
- name: Checkout PennyLane for release build
if: inputs.pennylane-version == 'release'
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/wheel_macos_x86_64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ jobs:
run: |
mkdir -p ${{ github.workspace}}/Kokkos_install/${{ matrix.exec_model }}
cd kokkos
python -m pip install cmake ninja
# Omitting the installation of cmake v3.29.0 due to
# https://github.com/scikit-build/cmake-python-distributions/pull/474
python -m pip install "cmake!=3.29.0" ninja
cmake -BBuild . -DCMAKE_INSTALL_PREFIX=${{ github.workspace}}/Kokkos_install/${{ matrix.exec_model }} \
-DKokkos_ENABLE_COMPLEX_ALIGN=OFF \
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/wheel_noarch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ jobs:
- name: Install CMake and ninja
run: |
python -m pip install --upgrade cmake ninja
# Omitting the installation of cmake v3.29.0 due to
# https://github.com/scikit-build/cmake-python-distributions/pull/474
python -m pip install --upgrade "cmake!=3.29.0" ninja
- name: Build wheels
if: ${{ matrix.pl_backend == 'lightning_qubit'}}
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/wheel_win_x86_64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ jobs:
- name: Install dependencies
if: steps.kokkos-cache.outputs.cache-hit != 'true'
run: |
python -m pip install cmake build
# Omitting the installation of cmake v3.29.0 due to
# https://github.com/scikit-build/cmake-python-distributions/pull/474
python -m pip install "cmake!=3.29.0" build
- name: Build Kokkos core library
if: steps.kokkos-cache.outputs.cache-hit != 'true'
Expand Down
4 changes: 2 additions & 2 deletions mpitests/test_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ def test_dev_reset(self, tol, dev_mpi):
comm.Scatter(state_vector, local_state_vector, root=0)
dev_cpu = qml.device("lightning.qubit", wires=num_wires, c_dtype=c_dtype)

dev_cpu.reset()
dev_cpu._statevector.reset_state()

def circuit():
qml.PauliX(wires=[0])
Expand Down Expand Up @@ -556,7 +556,7 @@ def circuit():

cpu_qnode = qml.QNode(circuit, dev_cpu)
expected_output_cpu = cpu_qnode()
comm.Bcast(expected_output_cpu, root=0)
comm.Bcast(np.array(expected_output_cpu), root=0)

mpi_qnode = qml.QNode(circuit, dev_mpi)
expected_output_mpi = mpi_qnode()
Expand Down
39 changes: 27 additions & 12 deletions pennylane_lightning/core/_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
r"""
Helper functions for serializing quantum tapes.
"""
from typing import List, Tuple
from typing import List, Sequence, Tuple

import numpy as np
from pennylane import (
Expand All @@ -34,6 +34,7 @@
)
from pennylane.math import unwrap
from pennylane.operation import Tensor
from pennylane.ops import Prod, SProd, Sum
from pennylane.tape import QuantumTape

pauli_name_map = {
Expand Down Expand Up @@ -183,19 +184,22 @@ def _named_obs(self, observable, wires_map: dict = None):

def _hermitian_ob(self, observable, wires_map: dict = None):
"""Serializes a Hermitian observable"""
assert not isinstance(observable, Tensor)

wires = [wires_map[w] for w in observable.wires] if wires_map else observable.wires.tolist()
return self.hermitian_obs(matrix(observable).ravel().astype(self.ctype), wires)

def _tensor_ob(self, observable, wires_map: dict = None):
"""Serialize a tensor observable"""
assert isinstance(observable, Tensor)
return self.tensor_obs([self._ob(obs, wires_map) for obs in observable.obs])
obs = observable.obs if isinstance(observable, Tensor) else observable.operands
return self.tensor_obs([self._ob(o, wires_map) for o in obs])

def _hamiltonian(self, observable, wires_map: dict = None):
coeffs = np.array(unwrap(observable.coeffs)).astype(self.rtype)
terms = [self._ob(t, wires_map) for t in observable.ops]
coeffs, ops = observable.terms()
coeffs = np.array(unwrap(coeffs)).astype(self.rtype)
terms = [self._ob(t, wires_map) for t in ops]
# TODO: This is in case `_hamiltonian` is called recursively which would cause a list
# to be passed where `_ob` expects an observable.
terms = [t[0] if isinstance(t, Sequence) and len(t) == 1 else t for t in terms]

if self.split_obs:
return [self.hamiltonian_obs([c], [t]) for (c, t) in zip(coeffs, terms)]
Expand Down Expand Up @@ -254,23 +258,33 @@ def _pauli_sentence(self, observable, wires_map: dict = None):
terms = [self._pauli_word(pw, wires_map) for pw in pwords]
coeffs = np.array(coeffs).astype(self.rtype)

# TODO: Add this
# if len(terms) == 1 and coeffs[0] == 1.0:
# return terms[0]

if self.split_obs:
return [self.hamiltonian_obs([c], [t]) for (c, t) in zip(coeffs, terms)]
return self.hamiltonian_obs(coeffs, terms)

# pylint: disable=protected-access
# pylint: disable=protected-access, too-many-return-statements
def _ob(self, observable, wires_map: dict = None):
"""Serialize a :class:`pennylane.operation.Observable` into an Observable."""
if isinstance(observable, Tensor):
if isinstance(observable, (Prod, Sum, SProd)) and observable.pauli_rep is not None:
return self._pauli_sentence(observable.pauli_rep, wires_map)
if isinstance(observable, Tensor) or (
isinstance(observable, Prod) and not observable.has_overlapping_wires
):
return self._tensor_ob(observable, wires_map)
if observable.name == "Hamiltonian":
if observable.name in ("Hamiltonian", "LinearCombination"):
return self._hamiltonian(observable, wires_map)
if observable.name == "SparseHamiltonian":
return self._sparse_hamiltonian(observable, wires_map)
if isinstance(observable, (PauliX, PauliY, PauliZ, Identity, Hadamard)):
return self._named_obs(observable, wires_map)
if observable._pauli_rep is not None:
return self._pauli_sentence(observable._pauli_rep, wires_map)
if observable.pauli_rep is not None:
return self._pauli_sentence(observable.pauli_rep, wires_map)
# if isinstance(observable, (Prod, Sum)):
# return self._hamiltonian(observable, wires_map)
return self._hermitian_ob(observable, wires_map)

def serialize_observables(self, tape: QuantumTape, wires_map: dict = None) -> List:
Expand All @@ -282,7 +296,8 @@ def serialize_observables(self, tape: QuantumTape, wires_map: dict = None) -> Li
Returns:
list(ObsStructC128 or ObsStructC64): A list of observable objects compatible with
the C++ backend
the C++ backend. For unsupported observables, the observable matrix is used
to create a :class:`~pennylane.Hermitian` to be used for serialization.
"""

serialized_obs = []
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.36.0-dev18"
__version__ = "0.36.0-dev19"
60 changes: 56 additions & 4 deletions pennylane_lightning/core/lightning_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
import pennylane as qml
from pennylane import BasisState, QubitDevice, StatePrep
from pennylane.devices import DefaultQubitLegacy
from pennylane.measurements import MeasurementProcess
from pennylane.operation import Operation
from pennylane.measurements import Expectation, MeasurementProcess, State
from pennylane.operation import Operation, Tensor
from pennylane.ops import Prod, Projector, SProd, Sum
from pennylane.wires import Wires

from ._serialize import QuantumScriptSerializer
Expand Down Expand Up @@ -306,18 +307,69 @@ def _process_jacobian_tape(
"obs_idx_offsets": obs_idx_offsets,
}

@staticmethod
def _assert_adjdiff_no_projectors(observable):
"""Helper function to validate that an observable is not or does not contain
Projectors
Args:
observable (~pennylane.operation.Operator): Observable to check
Raises:
~pennylane.QuantumFunctionError: if a ``Projector`` is found.
"""
if isinstance(observable, Tensor):
if any(isinstance(o, Projector) for o in observable.non_identity_obs):
raise qml.QuantumFunctionError(
"Adjoint differentiation method does not support the Projector observable"
)

elif isinstance(observable, Projector):
raise qml.QuantumFunctionError(
"Adjoint differentiation method does not support the Projector observable"
)

elif isinstance(observable, SProd):
LightningBase._assert_adjdiff_no_projectors(observable.base)

elif isinstance(observable, (Sum, Prod)):
for obs in observable:
LightningBase._assert_adjdiff_no_projectors(obs)

# pylint: disable=unnecessary-pass
@staticmethod
def _check_adjdiff_supported_measurements(measurements: List[MeasurementProcess]):
"""Check whether given list of measurement is supported by adjoint_differentiation.
"""Check whether given list of measurements is supported by adjoint_differentiation.
Args:
measurements (List[MeasurementProcess]): a list of measurement processes to check.
Returns:
Expectation or State: a common return type of measurements.
Raises:
~pennylane.QuantumFunctionError: if a measurement is unsupported with adjoint
differentiation.
"""
pass
if not measurements:
return None

if len(measurements) == 1 and measurements[0].return_type is State:
# return State
raise qml.QuantumFunctionError(
"Adjoint differentiation does not support State measurements."
)

# The return_type of measurement processes must be expectation
if any(m.return_type is not Expectation for m in measurements):
raise qml.QuantumFunctionError(
"Adjoint differentiation method does not support expectation return type "
"mixed with other return types"
)

for measurement in measurements:
LightningBase._assert_adjdiff_no_projectors(measurement.obs)
return Expectation

@staticmethod
def _adjoint_jacobian_processing(jac):
Expand Down
8 changes: 8 additions & 0 deletions pennylane_lightning/core/src/bindings/Bindings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ void registerBackendAgnosticObservables(py::module_ &m) {
.def("__repr__", &HermitianObs<StateVectorT>::getObsName)
.def("get_wires", &HermitianObs<StateVectorT>::getWires,
"Get wires of observables")
.def("get_matrix", &HermitianObs<StateVectorT>::getMatrix,
"Get matrix representation of Hermitian operator")
.def(
"__eq__",
[](const HermitianObs<StateVectorT> &self,
Expand All @@ -373,6 +375,8 @@ void registerBackendAgnosticObservables(py::module_ &m) {
.def("__repr__", &TensorProdObs<StateVectorT>::getObsName)
.def("get_wires", &TensorProdObs<StateVectorT>::getWires,
"Get wires of observables")
.def("get_ops", &TensorProdObs<StateVectorT>::getObs,
"Get operations list")
.def(
"__eq__",
[](const TensorProdObs<StateVectorT> &self,
Expand Down Expand Up @@ -401,6 +405,10 @@ void registerBackendAgnosticObservables(py::module_ &m) {
.def("__repr__", &Hamiltonian<StateVectorT>::getObsName)
.def("get_wires", &Hamiltonian<StateVectorT>::getWires,
"Get wires of observables")
.def("get_ops", &Hamiltonian<StateVectorT>::getObs,
"Get operations contained by Hamiltonian")
.def("get_coeffs", &Hamiltonian<StateVectorT>::getCoeffs,
"Get Hamiltonian coefficients")
.def(
"__eq__",
[](const Hamiltonian<StateVectorT> &self,
Expand Down
51 changes: 3 additions & 48 deletions pennylane_lightning/lightning_gpu/lightning_gpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,8 @@
from typing import List, Union

import pennylane as qml
from pennylane import (
BasisState,
DeviceError,
Projector,
QuantumFunctionError,
Rot,
StatePrep,
math,
)
from pennylane.measurements import Expectation, MeasurementProcess, State
from pennylane.operation import Tensor
from pennylane import BasisState, DeviceError, QuantumFunctionError, Rot, StatePrep, math
from pennylane.measurements import Expectation, State
from pennylane.ops.op_math import Adjoint
from pennylane.wires import Wires

Expand Down Expand Up @@ -196,6 +187,7 @@ def _mebibytesToBytes(mebibytes):
"Hadamard",
"SparseHamiltonian",
"Hamiltonian",
"LinearCombination",
"Hermitian",
"Identity",
"Sum",
Expand Down Expand Up @@ -583,43 +575,6 @@ def apply(self, operations, rotations=None, **kwargs):

self.apply_lightning(operations)

@staticmethod
def _check_adjdiff_supported_measurements(measurements: List[MeasurementProcess]):
"""Check whether given list of measurement is supported by adjoint_diff.
Args:
measurements (List[MeasurementProcess]): a list of measurement processes to check.
Returns:
Expectation or State: a common return type of measurements.
"""
if not measurements:
return None

if len(measurements) == 1 and measurements[0].return_type is State:
# return State
raise QuantumFunctionError(
"Adjoint differentiation does not support State measurements."
)

# The return_type of measurement processes must be expectation
if any(m.return_type is not Expectation for m in measurements):
raise QuantumFunctionError(
"Adjoint differentiation method does not support expectation return type "
"mixed with other return types"
)

for measurement in measurements:
if isinstance(measurement.obs, Tensor):
if any(isinstance(o, Projector) for o in measurement.obs.non_identity_obs):
raise QuantumFunctionError(
"Adjoint differentiation method does not support the "
"Projector observable"
)
elif isinstance(measurement.obs, Projector):
raise QuantumFunctionError(
"Adjoint differentiation method does not support the Projector observable"
)
return Expectation

@staticmethod
def _check_adjdiff_supported_operations(operations):
"""Check Lightning adjoint differentiation method support for a tape.
Expand Down
Loading

0 comments on commit 044ffe8

Please sign in to comment.