Skip to content

Commit

Permalink
Update QuantumScriptSerializer.serialize_observables to better hand…
Browse files Browse the repository at this point in the history
…le new operator arithmetic (#670)

* port PR changes so far, after traumatic rebase

* update vjp tests

* format

* update vjp tests

* update dev version

* format

* add tests for vjp

* Auto update version

* Auto update version

* Updated tests

* Updated serialization

* Unpinned cmake

* Update changelog

* Update .github/CHANGELOG.md

* isort

* black

* Run CI with updated PL branch

* Auto update version

* trigger ci

* Added changes per review

* Auto update version

* Update requirements-dev.txt

* Update pennylane_lightning/core/_serialize.py

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

* Auto update version

* Trigger CI

* Update overlapping wires prod serialization test

* Auto update version

* Trigger CI

---------

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: Ali Asadi <[email protected]>
  • Loading branch information
6 people authored Apr 10, 2024
1 parent 9ec7126 commit c6a8260
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 218 deletions.
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
* Add `isort` to `requirements-dev.txt` and run before `black` upon `make format` to sort Python imports.
[(#623)](https://github.com/PennyLaneAI/pennylane-lightning/pull/623)

* Improve support for new operator arithmetic with `QuantumScriptSerializer.serialize_observables`.
[(#670)](https://github.com/PennyLaneAI/pennylane-lightning/pull/670)

### Documentation

### Bug fixes
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/tests_gpu_cuda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,7 @@ jobs:
- name: Install required packages
run: |
# 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 }}
python -m pip install ninja cmake custatevec-cu${{ matrix.cuda_version }}
sudo apt-get -y -q install liblapack-dev
- name: Build and run unit tests
Expand Down Expand Up @@ -242,9 +240,7 @@ jobs:
run: |
cd main
python -m pip install -r requirements-dev.txt
# 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
python -m pip install cmake custatevec-cu${{ matrix.cuda_version }} openfermionpyscf
- name: Checkout PennyLane for release build
if: inputs.pennylane-version == 'release'
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/tests_linux_x86_mpi_gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ jobs:
- name: Install required packages
run: |
python -m pip install -r requirements-dev.txt
# 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 scipy
python -m pip install cmake custatevec-cu12 scipy
- name: Validate GPU version and installed compiler and modules
run: |
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/wheel_macos_x86_64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ jobs:
run: |
mkdir -p ${{ github.workspace}}/Kokkos_install/${{ matrix.exec_model }}
cd kokkos
# 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
python -m pip install cmake ninja
cmake -BBuild . -DCMAKE_INSTALL_PREFIX=${{ github.workspace}}/Kokkos_install/${{ matrix.exec_model }} \
-DKokkos_ENABLE_COMPLEX_ALIGN=OFF \
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/wheel_noarch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ jobs:
- name: Install CMake and ninja
run: |
# 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
python -m pip install --upgrade cmake ninja
- name: Build wheels
if: ${{ matrix.pl_backend == 'lightning_qubit'}}
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/wheel_win_x86_64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ jobs:
- name: Install dependencies
if: steps.kokkos-cache.outputs.cache-hit != 'true'
run: |
# 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
python -m pip install cmake build
- name: Build Kokkos core library
if: steps.kokkos-cache.outputs.cache-hit != 'true'
Expand Down
38 changes: 18 additions & 20 deletions pennylane_lightning/core/_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
BasisState,
DeviceError,
Hadamard,
Hamiltonian,
Identity,
PauliX,
PauliY,
Expand All @@ -34,10 +33,12 @@
)
from pennylane.math import unwrap
from pennylane.operation import Tensor
from pennylane.ops import Prod, SProd, Sum
from pennylane.ops import Hamiltonian, LinearCombination, Prod, SProd, Sum
from pennylane.tape import QuantumTape

pauli_name_map = {
NAMED_OBS = (Identity, PauliX, PauliY, PauliZ, Hadamard)
OP_MATH_OBS = (Prod, SProd, Sum, LinearCombination)
PAULI_NAME_MAP = {
"I": "Identity",
"X": "PauliX",
"Y": "PauliY",
Expand Down Expand Up @@ -243,11 +244,11 @@ def map_wire(wire: int):

if len(observable) == 1:
wire, pauli = list(observable.items())[0]
return self.named_obs(pauli_name_map[pauli], [map_wire(wire)])
return self.named_obs(PAULI_NAME_MAP[pauli], [map_wire(wire)])

return self.tensor_obs(
[
self.named_obs(pauli_name_map[pauli], [map_wire(wire)])
self.named_obs(PAULI_NAME_MAP[pauli], [map_wire(wire)])
for wire, pauli in observable.items()
]
)
Expand All @@ -258,9 +259,8 @@ 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 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)]
Expand All @@ -269,22 +269,20 @@ def _pauli_sentence(self, observable, wires_map: dict = None):
# 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, (Prod, Sum, SProd)) and observable.pauli_rep is not None:
if isinstance(observable, NAMED_OBS):
return self._named_obs(observable, wires_map)
if isinstance(observable, Hamiltonian):
return self._hamiltonian(observable, wires_map)
if 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
):
if isinstance(observable, (Tensor, Prod)):
if isinstance(observable, Prod) and observable.has_overlapping_wires:
return self._hermitian_ob(observable, wires_map)
return self._tensor_ob(observable, wires_map)
if observable.name in ("Hamiltonian", "LinearCombination"):
if isinstance(observable, OP_MATH_OBS):
return self._hamiltonian(observable, wires_map)
if observable.name == "SparseHamiltonian":
if isinstance(observable, 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 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 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-dev24"
__version__ = "0.36.0-dev25"
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ clang-tidy~=16.0
clang-format~=16.0
isort==5.13.2
click==8.0.4
cmake==3.28.4
cmake
custatevec-cu12
pylint
scipy
10 changes: 2 additions & 8 deletions tests/test_adjoint_jacobian.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,14 +1008,8 @@ def f(params1, params2):
qml.RY(tf.cos(params2), wires=[0])
return qml.expval(qml.PauliZ(0))

if dev._new_API:
# tf expects float32 with new device API
tf_r_dtype = tf.float32
h = 2e-3
tol = 1e-3
else:
tf_r_dtype = tf.float32 if dev.dtype == np.complex64 else tf.float64
tol, h = get_tolerance_and_stepsize(dev, step_size=True)
tf_r_dtype = tf.float32 if dev.dtype == np.complex64 else tf.float64
tol, h = get_tolerance_and_stepsize(dev, step_size=True)

params1 = tf.Variable(0.3, dtype=tf_r_dtype)
params2 = tf.Variable(0.4, dtype=tf_r_dtype)
Expand Down
Loading

0 comments on commit c6a8260

Please sign in to comment.