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 explicit serialization support for Obs and Ops binding classes for H distribution #591

Draft
wants to merge 39 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7aee037
Add explicit serialization support for Obs and Ops binding classes
mlxd Jan 11, 2024
c125042
Auto update version
github-actions[bot] Jan 11, 2024
f4b5516
Fix kokkos complex bindings
mlxd Jan 11, 2024
2bf05a7
Merge branch 'update/pickle_bindings' of github.com:PennyLaneAI/penny…
mlxd Jan 11, 2024
6b1c229
Add binding support for SV serialization
mlxd Jan 12, 2024
b6f8c10
Remove unneeded copy from LK ctor
mlxd Jan 12, 2024
f2cf1e2
Fix ctor arg name
mlxd Jan 12, 2024
bab0318
Ensure batching and observables are compliant with SV serialization a…
mlxd Jan 12, 2024
8a072ee
Merge branch 'master' into update/pickle_bindings
mlxd Jan 12, 2024
cc1cd74
Fix obs name formatting
mlxd Jan 12, 2024
660acf7
Merge branch 'update/pickle_bindings' of github.com:PennyLaneAI/penny…
mlxd Jan 12, 2024
d879cf1
Once again fix naming with obs
mlxd Jan 12, 2024
cb3f7ad
Fix CT errors
mlxd Jan 12, 2024
8c3013d
Fix data-to-host copies, ownership and add SV-to-host serialization s…
mlxd Jan 13, 2024
2fb20f3
Fix LGPU memory local tags and ensure serialization works
mlxd Jan 13, 2024
874e4e0
Add Python layer support for LK batching with envvar
mlxd Jan 13, 2024
8b5c0f5
Fix missing max func call
mlxd Jan 13, 2024
f10c2ae
Update high-level args, const-ness and serialisation
mlxd Jan 15, 2024
516b2df
Ensure tuple return uses buffer rather than explicit entries
mlxd Jan 15, 2024
7883394
Fix jac extension in LK
mlxd Jan 15, 2024
a2fd0e9
Fix data corruption due to improper type spec in buffer
mlxd Jan 15, 2024
724d035
Ensure additional copies are avoided with LK+Ham
mlxd Jan 16, 2024
f034b81
Auto update version
github-actions[bot] Jan 16, 2024
7f9ea5e
Create SV-less serialiser for adjoint
mlxd Jan 18, 2024
18c222a
Remove additional print
mlxd Jan 18, 2024
977a52c
No more outputs
mlxd Jan 19, 2024
7c0cdba
Add missing move adjoint bindings for LQ
mlxd Jan 19, 2024
b6b895b
Auto update version
github-actions[bot] Jan 19, 2024
320ce3c
Merge branch 'master' into update/pickle_bindings
mlxd Jan 22, 2024
bb409d8
Auto update version
github-actions[bot] Jan 22, 2024
92e6132
Allow fwd pass to execute remotely
mlxd Jan 24, 2024
cccd070
Allow fwd and bwd pass to use multiple resources, controlled by env-var
mlxd Jan 25, 2024
8cd631a
Remove pre-rot state for LK saving 1 GPU buffer
mlxd Jan 25, 2024
abbc9d3
Ensure batch sizes passed correctly
mlxd Jan 30, 2024
8370d8c
Ensure PKL5 used
mlxd Jan 30, 2024
92feda2
Allow better tracking of H terms
mlxd Jan 31, 2024
b647aae
Remove SV from adjoint distribution
mlxd Feb 6, 2024
52f6392
Merge branch 'master' into update/pickle_bindings
mlxd Feb 14, 2024
3dcfa8d
Auto update version
github-actions[bot] Feb 14, 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
73 changes: 60 additions & 13 deletions pennylane_lightning/core/_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
r"""
Helper functions for serializing quantum tapes.
"""
from typing import List, Tuple

from itertools import islice, chain

Check notice on line 18 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L18

Unused chain imported from itertools (unused-import)
from typing import List, Sequence, Tuple, Union
import numpy as np
from pennylane import (
BasisState,
Expand All @@ -30,8 +32,10 @@
QubitUnitary,
)
from pennylane.operation import Tensor
from pennylane.tape import QuantumTape

Check notice on line 35 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L35

Unused is_pauli_word imported from pennylane.pauli (unused-import)
from pennylane.math import unwrap

Check notice on line 36 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L36

Unused SProd imported from pennylane.ops (unused-import)

Check notice on line 36 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L36

Unused Prod imported from pennylane.ops (unused-import)

Check notice on line 36 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L36

Unused Sum imported from pennylane.ops (unused-import)
from pennylane.pauli import is_pauli_word
from pennylane.ops import Prod, SProd, Sum

from pennylane import matrix, DeviceError

Expand All @@ -40,9 +44,21 @@
"X": "PauliX",
"Y": "PauliY",
"Z": "PauliZ",
"Identity": "Identity",
"PauliX": "PauliX",
"PauliY": "PauliY",
"PauliZ": "PauliZ",
}


def _chunk_iterable(iteration, num_chunks):
"""Lazy-evaluated chunking of given iterable from https://stackoverflow.com/a/22045226
Replicated from lightning_base to avoid circular import
"""
iteration = iter(iteration)
return iter(lambda: tuple(islice(iteration, num_chunks)), ())


class QuantumScriptSerializer:
"""Serializer class for `pennylane.tape.QuantumScript` data.

Expand All @@ -54,7 +70,11 @@

# pylint: disable=import-outside-toplevel, too-many-instance-attributes, c-extension-no-member
def __init__(
self, device_name, use_csingle: bool = False, use_mpi: bool = False, split_obs: bool = False
self,
device_name,
use_csingle: bool = False,
use_mpi: bool = False,
split_obs: Union[bool, int] = False,
):
self.use_csingle = use_csingle
self.device_name = device_name
Expand Down Expand Up @@ -190,14 +210,36 @@
assert isinstance(observable, Tensor)
return self.tensor_obs([self._ob(obs, wires_map) for obs in observable.obs])

def _chunk_ham_terms(self, coeffs, ops, wires_map: dict, split_num: int) -> List:

Check notice on line 213 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L213

Unused argument 'wires_map' (unused-argument)
"Create split_num sub-Hamiltonians from a single high term-count Hamiltonian"
num_terms = len(coeffs)
step_size = int(np.ceil((1.0 * num_terms) / split_num))
c_coeffs = list(_chunk_iterable(coeffs, step_size))
c_ops = list(_chunk_iterable(ops, step_size))
return c_coeffs, c_ops

def _hamiltonian(self, observable, wires_map: dict):
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)
ops_l = []
for t in ops:
term_cpp = self._ob(t, wires_map)
if isinstance(term_cpp, Sequence):
ops_l.extend(term_cpp)
else:
ops_l.append(term_cpp)

if self.split_obs:
return [self.hamiltonian_obs([c], [t]) for (c, t) in zip(coeffs, terms)]
if isinstance(self.split_obs, int):
"Split into `split_obs` sub-Hamiltonian chunks"

Check notice on line 234 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L234

String statement has no effect (pointless-string-statement)
c, o = self._chunk_ham_terms(coeffs, ops_l, wires_map, self.split_obs)
out = [self.hamiltonian_obs(c_coeffs, c_obs) for (c_coeffs, c_obs) in zip(c, o)]
return out

Check notice on line 238 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L238

String statement has no effect (pointless-string-statement)
return self.hamiltonian_obs(coeffs, terms)
"Split until each term is an individual H"
return [self.hamiltonian_obs([c], [t]) for (c, t) in zip(coeffs, ops_l)]

return self.hamiltonian_obs(coeffs, ops_l)

def _sparse_hamiltonian(self, observable, wires_map: dict):
"""Serialize an observable (Sparse Hamiltonian)
Expand Down Expand Up @@ -256,14 +298,14 @@
# pylint: disable=protected-access
def _ob(self, observable, wires_map):
"""Serialize a :class:`pennylane.operation.Observable` into an Observable."""
if isinstance(observable, (PauliX, PauliY, PauliZ, Identity, Hadamard)):
return self._named_obs(observable, wires_map)
if isinstance(observable, Tensor):
return self._tensor_ob(observable, wires_map)
if observable.name == "Hamiltonian":
if observable.name in ("Hamiltonian"):
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)
return self._hermitian_ob(observable, wires_map)
Expand All @@ -286,11 +328,13 @@
for observable in tape.observables:
ser_ob = self._ob(observable, wires_map)
if isinstance(ser_ob, list):
num_terms = sum([o.num_terms() for o in ser_ob])

Check notice on line 331 in pennylane_lightning/core/_serialize.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/core/_serialize.py#L331

Consider using a generator instead 'sum(o.num_terms() for o in ser_ob)' (consider-using-generator)
serialized_obs.extend(ser_ob)
offset_indices.append(offset_indices[-1] + len(ser_ob))
offset_indices.append(offset_indices[-1] + num_terms)
else:
num_terms = ser_ob.num_terms()
serialized_obs.append(ser_ob)
offset_indices.append(offset_indices[-1] + 1)
offset_indices.append(offset_indices[-1] + num_terms)
return serialized_obs, offset_indices

def serialize_ops(
Expand Down Expand Up @@ -351,13 +395,16 @@
return single_op, name, wires_list, controlled_wires_list, control_values_list

for operation in tape.operations:
op_list = []
if isinstance(operation, (BasisState, StatePrep)):
uses_stateprep = True
# TODO: identify state-prep offsets
# op_list.extend(chain(*[op.decomposition() for op in operation.expand().operations]))
continue
if isinstance(operation, Rot):
op_list = operation.expand().operations
op_list.extend(operation.expand().operations)
else:
op_list = [operation]
op_list.append(operation)

for single_op in op_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.35.0-dev14"
__version__ = "0.35.0-dev15"
6 changes: 4 additions & 2 deletions pennylane_lightning/core/lightning_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
This module contains the base class for all PennyLane Lightning simulator devices,
and interfaces with C++ for improved performance.
"""
from typing import List
from typing import List, Union
from itertools import islice, product
import numpy as np

Expand Down Expand Up @@ -73,7 +73,8 @@ def __init__(
*,
c_dtype=np.complex128,
shots=None,
batch_obs=False,
batch_obs: Union[bool, int] = False,
mpi: bool = False,
):
if c_dtype is np.complex64:
r_dtype = np.float32
Expand All @@ -85,6 +86,7 @@ def __init__(
raise TypeError(f"Unsupported complex Type: {c_dtype}")
super().__init__(wires, shots=shots, r_dtype=r_dtype, c_dtype=c_dtype)
self._batch_obs = batch_obs
self._mpi = mpi

@property
def stopping_condition(self):
Expand Down
Loading