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

Add the support class for the Adjoint Jacobian to the new device #907

Merged
merged 49 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
120bbed
include the new device base class
LuisAlfredoNu Sep 4, 2024
bdf4daa
add measurements
LuisAlfredoNu Sep 9, 2024
b05a6a4
State vector almos done
LuisAlfredoNu Sep 9, 2024
5dac907
tmp commit
LuisAlfredoNu Sep 9, 2024
bfd0771
Solve prop issue
LuisAlfredoNu Sep 9, 2024
a1ff6c6
ready measurenment class for LGPU
LuisAlfredoNu Sep 10, 2024
a0cfb1d
print helps for measurements
LuisAlfredoNu Sep 10, 2024
f472471
Merge gpuNewAPI_simulate
LuisAlfredoNu Sep 11, 2024
c7ac82d
grammar correction
LuisAlfredoNu Sep 11, 2024
6627913
cleaning code
LuisAlfredoNu Sep 11, 2024
6290953
apply format
LuisAlfredoNu Sep 11, 2024
219262b
delete usuless variables
LuisAlfredoNu Sep 11, 2024
bca1a74
delete prints
LuisAlfredoNu Sep 11, 2024
0f8f957
Revert change in measurenment test
LuisAlfredoNu Sep 11, 2024
a9ccf62
Merge branch 'gpuNewAPI_backend' into gpuNewAPI_simulate
LuisAlfredoNu Sep 11, 2024
a99b6e8
Merge branch 'gpuNewAPI_backend' into gpuNewAPI_simulate
LuisAlfredoNu Sep 11, 2024
0399f18
add simulate method
LuisAlfredoNu Sep 11, 2024
23d5696
apply format
LuisAlfredoNu Sep 11, 2024
585c313
Shuli suggestion
LuisAlfredoNu Sep 11, 2024
5eee8eb
apply format
LuisAlfredoNu Sep 11, 2024
be3c6f7
Develop Jacobian
LuisAlfredoNu Sep 11, 2024
7ff13b3
unlock the test for jacobian and adjoint-jacobian
LuisAlfredoNu Sep 11, 2024
3cec8b1
apply format
LuisAlfredoNu Sep 11, 2024
92089eb
Update pennylane_lightning/lightning_gpu/_mpi_handler.py
LuisAlfredoNu Sep 12, 2024
196042a
Apply suggestions from code review Vinvent's comments
LuisAlfredoNu Sep 12, 2024
b4ed1ae
Vincent's comments
LuisAlfredoNu Sep 12, 2024
695283b
Merge branch 'gpuNewAPI_simulate' of github.com:PennyLaneAI/pennylane…
LuisAlfredoNu Sep 12, 2024
1729d06
apply format
LuisAlfredoNu Sep 12, 2024
38ddbdb
Merge branch 'gpuNewAPI_simulate' into gpuNewAPI_AdjJaco
LuisAlfredoNu Sep 12, 2024
5819efc
Apply suggestions from code review. Vincent's suggestion
LuisAlfredoNu Sep 13, 2024
2dbc7db
review comments
LuisAlfredoNu Sep 13, 2024
0630edf
apply format
LuisAlfredoNu Sep 13, 2024
3fa8409
apply format
LuisAlfredoNu Sep 13, 2024
af16b8d
Ali suggestion 1
LuisAlfredoNu Sep 13, 2024
0cb050f
add reset
LuisAlfredoNu Sep 16, 2024
54afeb5
apply_basis_state as abstract in GPU
LuisAlfredoNu Sep 16, 2024
ac87663
apply format
LuisAlfredoNu Sep 16, 2024
35270fb
Apply suggestions from code review Ali suggestion docs
LuisAlfredoNu Sep 16, 2024
f51cbb9
propagate namming suggestion
LuisAlfredoNu Sep 16, 2024
29675e7
Merge branch 'gpuNewAPI_simulate' into gpuNewAPI_AdjJaco
LuisAlfredoNu Sep 16, 2024
65e66e9
Apply suggestions from code review. Ali's suggestion 3
LuisAlfredoNu Sep 16, 2024
0472fdd
solve errors with kokkos
LuisAlfredoNu Sep 16, 2024
96728cb
apply format
LuisAlfredoNu Sep 16, 2024
5901a64
Merge branch 'gpuNewAPI_simulate' into gpuNewAPI_AdjJaco
LuisAlfredoNu Sep 16, 2024
112ead0
solve conflicts
LuisAlfredoNu Sep 16, 2024
1acf4db
Merge branch 'gpuNewAPI_backend' into gpuNewAPI_AdjJaco
LuisAlfredoNu Sep 16, 2024
87778d6
apply format
LuisAlfredoNu Sep 16, 2024
c493d47
solve issue with reset
LuisAlfredoNu Sep 16, 2024
faead9c
solve error with kokkos
LuisAlfredoNu Sep 17, 2024
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
1 change: 0 additions & 1 deletion pennylane_lightning/core/_state_vector_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ def _apply_basis_state(self, state, wires, use_async: Optional[bool] = None):
raise ValueError("BasisState parameter and wires must be of equal length.")

# Return a computational basis state over all wires.
print("FSX:", use_async)
if use_async == None:
self._qubit_state.setBasisState(list(state), list(wires))
else:
Expand Down
5 changes: 3 additions & 2 deletions pennylane_lightning/core/lightning_newAPI_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def __init__( # pylint: disable=too-many-arguments

self._c_dtype = c_dtype
self._batch_obs = batch_obs
self._sync = None

if isinstance(wires, int):
self._wire_map = None # should just use wires as is
Expand Down Expand Up @@ -133,7 +134,7 @@ def jacobian(
"""
if wire_map is not None:
[circuit], _ = qml.map_wires(circuit, wire_map)
state.reset_state()
state.reset_state(self._sync)
final_state = state.get_final_state(circuit)
return self.LightningAdjointJacobian(final_state, batch_obs=batch_obs).calculate_jacobian(
circuit
Expand Down Expand Up @@ -191,7 +192,7 @@ def vjp( # pylint: disable=too-many-arguments
"""
if wire_map is not None:
[circuit], _ = qml.map_wires(circuit, wire_map)
state.reset_state()
state.reset_state(self._sync)
final_state = state.get_final_state(circuit)
return self.LightningAdjointJacobian(final_state, batch_obs=batch_obs).calculate_vjp(
circuit, cotangents
Expand Down
91 changes: 88 additions & 3 deletions pennylane_lightning/lightning_gpu/_adjoint_jacobian.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,37 @@
Internal methods for adjoint Jacobian differentiation method.
"""

from warnings import warn

try:
from pennylane_lightning.lightning_gpu_ops.algorithms import (
AdjointJacobianC64,
AdjointJacobianC128,
create_ops_listC64,
create_ops_listC128,
)

try:
from pennylane_lightning.lightning_gpu_ops.algorithmsMPI import (
AdjointJacobianMPIC64,
AdjointJacobianMPIC128,
create_ops_listMPIC64,
create_ops_listMPIC128,
)

MPI_SUPPORT = True

Check warning on line 36 in pennylane_lightning/lightning_gpu/_adjoint_jacobian.py

View check run for this annotation

Codecov / codecov/patch

pennylane_lightning/lightning_gpu/_adjoint_jacobian.py#L36

Added line #L36 was not covered by tests
except ImportError as ex:
warn(str(ex), UserWarning)
MPI_SUPPORT = False

except ImportError as ex:
warn(str(ex), UserWarning)
pass

import numpy as np
import pennylane as qml
from pennylane.tape import QuantumTape
Comment on lines -19 to +46
Copy link
Member

Choose a reason for hiding this comment

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

👍


# pylint: disable=ungrouped-imports
from pennylane_lightning.core._adjoint_jacobian_base import LightningBaseAdjointJacobian

from ._state_vector import LightningGPUStateVector
Expand All @@ -31,5 +59,62 @@
batch_obs(bool): If serialized tape is to be batched or not.
"""

def __init__(self, lgpu_state: LightningGPUStateVector, batch_obs: bool = False) -> None:
super().__init__(lgpu_state, batch_obs)
# pylint: disable=too-few-public-methods

def __init__(self, qubit_state: LightningGPUStateVector, batch_obs: bool = False) -> None:
super().__init__(qubit_state, batch_obs)
# Initialize the C++ binds
self._jacobian_lightning, self._create_ops_list_lightning = self._adjoint_jacobian_dtype()

def _adjoint_jacobian_dtype(self):
"""Binding to Lightning GPU Adjoint Jacobian C++ class.

Returns: the AdjointJacobian class
"""
jacobian_lightning = (
AdjointJacobianC64() if self.dtype == np.complex64 else AdjointJacobianC128()
)
create_ops_list_lightning = (
create_ops_listC64 if self.dtype == np.complex64 else create_ops_listC128
)
return jacobian_lightning, create_ops_list_lightning

def calculate_jacobian(self, tape: QuantumTape):
"""Computes the Jacobian with the adjoint method.

.. code-block:: python

statevector = LightningGPUStateVector(num_wires=num_wires)
statevector = statevector.get_final_state(tape)
jacobian = LightningGPUAdjointJacobian(statevector).calculate_jacobian(tape)

Args:
tape (QuantumTape): Operations and measurements that represent instructions for execution on Lightning.

Returns:
The Jacobian of a tape.
"""

empty_array = self._handle_raises(tape, is_jacobian=True)

if empty_array:
return np.array([], dtype=self.dtype)

processed_data = self._process_jacobian_tape(tape)

if not processed_data: # training_params is empty
return np.array([], dtype=self.dtype)

trainable_params = processed_data["tp_shift"]
jac = self._jacobian_lightning(
processed_data["state_vector"],
processed_data["obs_serialized"],
processed_data["ops_serialized"],
trainable_params,
)
jac = np.array(jac)
jac = jac.reshape(-1, len(trainable_params)) if len(jac) else jac
jac_r = np.zeros((jac.shape[0], processed_data["all_params"]))
jac_r[:, processed_data["record_tp_rows"]] = jac

return self._adjoint_jacobian_processing(jac_r)
6 changes: 2 additions & 4 deletions pennylane_lightning/lightning_gpu/lightning_gpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@
LGPU_CPP_BINARY_AVAILABLE = True

try:
# pylint: disable=no-name-in-module
from pennylane_lightning.lightning_gpu_ops import DevTag, MPIManager

from ._mpi_handler import LightningGPU_MPIHandler
from ._mpi_handler import MPIHandler

MPI_SUPPORT = True
except ImportError as ex:
Expand Down Expand Up @@ -318,6 +315,7 @@ def _set_lightning_classes(self):
"""Load the LightningStateVector, LightningMeasurements, LightningAdjointJacobian as class attribute"""
self.LightningStateVector = LightningGPUStateVector
self.LightningMeasurements = LightningGPUMeasurements
self.LightningAdjointJacobian = LightningGPUAdjointJacobian

def _setup_execution_config(self, config):
"""
Expand Down
2 changes: 0 additions & 2 deletions pennylane_lightning/lightning_kokkos/_state_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,13 @@ def __init__(
num_wires,
dtype=np.complex128,
kokkos_args=None,
sync=True,
): # pylint: disable=too-many-arguments

super().__init__(num_wires, dtype)

self._device_name = "lightning.kokkos"

self._kokkos_config = {}
self._sync = sync
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In LK, any method requires the var sync


# Initialize the state vector
if kokkos_args is None:
Expand Down
4 changes: 1 addition & 3 deletions pennylane_lightning/lightning_kokkos/lightning_kokkos.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ def __init__( # pylint: disable=too-many-arguments
shots=None,
batch_obs=False,
# Kokkos arguments
sync=True,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The var sync is no longer needed in LK.

kokkos_args=None,
):
if not self._CPP_BINARY_AVAILABLE:
Expand All @@ -324,11 +323,10 @@ def __init__( # pylint: disable=too-many-arguments

# Kokkos specific options
self._kokkos_args = kokkos_args
self._sync = sync

# Creating the state vector
self._statevector = self.LightningStateVector(
num_wires=len(self.wires), dtype=c_dtype, kokkos_args=kokkos_args, sync=sync
num_wires=len(self.wires), dtype=c_dtype, kokkos_args=kokkos_args
)

if not LightningKokkos.kokkos_config:
Expand Down
5 changes: 3 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,16 @@ def get_device():
from pennylane_lightning.lightning_kokkos_ops import LightningException
elif device_name == "lightning.gpu":
from pennylane_lightning.lightning_gpu import LightningGPU as LightningDevice
from pennylane_lightning.lightning_gpu._adjoint_jacobian import (
LightningGPUAdjointJacobian as LightningAdjointJacobian,
)
from pennylane_lightning.lightning_gpu._measurements import (
LightningGPUMeasurements as LightningMeasurements,
)
from pennylane_lightning.lightning_gpu._state_vector import (
LightningGPUStateVector as LightningStateVector,
)

LightningAdjointJacobian = None

if hasattr(pennylane_lightning, "lightning_gpu_ops"):
import pennylane_lightning.lightning_gpu_ops as lightning_ops
from pennylane_lightning.lightning_gpu_ops import LightningException
Expand Down
20 changes: 14 additions & 6 deletions tests/lightning_qubit/test_adjoint_jacobian_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
allow_module_level=True,
)

if device_name == "lightning.gpu":
pytest.skip("LGPU new API in WIP. Skipping.", allow_module_level=True)

if device_name == "lightning.tensor":
pytest.skip("Skipping tests for the LightningTensor class.", allow_module_level=True)

Expand Down Expand Up @@ -423,7 +420,10 @@ def test_multiple_measurements(self, tol, lightning_sv):
statevector = lightning_sv(num_wires=2)
result_vjp = self.calculate_vjp(statevector, tape1, dy)

statevector.reset_state()
if device_name == "lightning.gpu":
statevector.reset_state(True)
else:
statevector.reset_state()

result_jac = self.calculate_jacobian(statevector, tape2)

Expand Down Expand Up @@ -483,7 +483,11 @@ def test_hermitian_expectation(self, tol, lightning_sv):
qml.expval(qml.Hermitian(obs, wires=(0,)))
tape.trainable_params = {0}

statevector.reset_state()
if device_name == "lightning.gpu":
statevector.reset_state(True)
else:
statevector.reset_state()

vjp = self.calculate_vjp(statevector, tape, dy)

assert np.allclose(vjp, -0.8 * np.sin(x), atol=tol)
Expand All @@ -500,7 +504,11 @@ def test_hermitian_tensor_expectation(self, tol, lightning_sv):
qml.expval(qml.Hermitian(obs, wires=(0,)) @ qml.PauliZ(wires=1))
tape.trainable_params = {0}

statevector.reset_state()
if device_name == "lightning.gpu":
statevector.reset_state(True)
else:
statevector.reset_state()

vjp = self.calculate_vjp(statevector, tape, dy)

assert np.allclose(vjp, -0.8 * np.sin(x), atol=tol)
Expand Down
3 changes: 0 additions & 3 deletions tests/lightning_qubit/test_jacobian_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
allow_module_level=True,
)

if device_name == "lightning.gpu":
pytest.skip("LGPU new API in WIP. Skipping.", allow_module_level=True)

if device_name == "lightning.tensor":
pytest.skip("Skipping tests for the LightningTensor class.", allow_module_level=True)

Expand Down
Loading