Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
131 changes: 131 additions & 0 deletions 00_Playground/LT-mps_custom_bond_dim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import numpy as np

Check notice on line 1 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L1

Missing module docstring (missing-module-docstring)
import pennylane as qml


# Function to define the bond dim for MPS on base to the number of qubits.
def setBondDims(numQubits, maxBondDim):

Check notice on line 6 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L6

Missing function or method docstring (missing-function-docstring)

Check notice on line 7 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L7

Trailing whitespace (trailing-whitespace)
log_maxBondDim = np.log2(maxBondDim)
limit_dimension = 2 ** int(log_maxBondDim)
localBondDims = np.ones(numQubits -1) * limit_dimension

Check notice on line 11 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L11

Trailing whitespace (trailing-whitespace)
for i, val in enumerate(localBondDims):

Check notice on line 12 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L12

Unused variable 'val' (unused-variable)
bondDim = min(i+1, numQubits - i - 1)
if bondDim <= log_maxBondDim:
localBondDims[i] = 2**bondDim

Check notice on line 16 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L16

Trailing whitespace (trailing-whitespace)
return localBondDims

Check notice on line 18 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L18

Trailing whitespace (trailing-whitespace)
def setSitesModes(numQubits):

Check notice on line 19 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L19

Missing function or method docstring (missing-function-docstring)
localSitesModes = []

Check notice on line 21 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L21

Trailing whitespace (trailing-whitespace)
for i in range(numQubits):
if i == 0:
localSite = [i, i+numQubits, -1]
elif i == numQubits - 1:
localSite = [i+numQubits-1, i, -1]
else:
localSite = [i + numQubits - 1, i , i + numQubits]

Check notice on line 29 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L29

Trailing whitespace (trailing-whitespace)
localSitesModes.append(localSite)

Check notice on line 31 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L31

Trailing whitespace (trailing-whitespace)
localSitesModes = np.array(localSitesModes)

Check notice on line 33 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L33

Trailing whitespace (trailing-whitespace)
return localSitesModes

def setSitesExtents(numQubits, bondDims):

Check notice on line 36 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L36

Missing function or method docstring (missing-function-docstring)
qubitDims = np.ones(numQubits,dtype=int) * 2
localSiteExtents = []
for i in range(numQubits):
if i == 0:
localSite = [qubitDims[i], bondDims[i], -1]
elif i == numQubits - 1:
localSite = [bondDims[i-1], qubitDims[i], -1]
else:
localSite = [bondDims[i-1], qubitDims[i], bondDims[i]]

Check notice on line 46 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L46

Trailing whitespace (trailing-whitespace)
localSiteExtents.append(localSite)

Check notice on line 48 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L48

Trailing whitespace (trailing-whitespace)
localSiteExtents = np.array(localSiteExtents).astype(int)

Check notice on line 50 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L50

Trailing whitespace (trailing-whitespace)
return localSiteExtents

# Function to print an MPS.
def print_mps(mps, full=False, name=None):
"""Print the MPOs."""

Check notice on line 56 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L56

Trailing whitespace (trailing-whitespace)
max_sites_length = 10

Check notice on line 58 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L58

Trailing whitespace (trailing-whitespace)
print("-"*100)
if name is not None:
print("MPS name:", name)

Check notice on line 62 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L62

Trailing whitespace (trailing-whitespace)
max_bond_dim = 0
for i, site in enumerate(mps):
max_bond_dim = max(max_bond_dim, site.shape[-1])

Check notice on line 66 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L66

Trailing whitespace (trailing-whitespace)
print("Sites:", len(mps), "| Max bond dim:", max_bond_dim)

Check notice on line 68 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L68

Trailing whitespace (trailing-whitespace)
max_rows = len(mps)//max_sites_length
if len(mps) % max_sites_length != 0:
max_rows += 1

Check notice on line 72 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L72

Trailing whitespace (trailing-whitespace)
for rows in range(max_rows):
for i in range(rows*max_sites_length, (rows+1)*max_sites_length):
print(f"| {'site '+str(i):^12}",end="")

Check notice on line 76 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L76

Trailing whitespace (trailing-whitespace)
print()
for i, site in enumerate(mps[rows*max_sites_length:(rows+1)*max_sites_length]):
print(f"| {str(site.shape):^12}", end="")
print()
print()

Check notice on line 82 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L82

Trailing whitespace (trailing-whitespace)
if full:
print("~"*100)
for i, site in enumerate(mps):
# print("Site", i, ":\n", site)
print("Site", i, " | Shape:", site.shape)

Check notice on line 87 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L87

Trailing whitespace (trailing-whitespace)
print(site)
print("~"*100)
print("-"*100)

# Create a random MPS with the custom dimensions
def create_MPS_with_custom_bondDims(numQubits,bondDims):

Check notice on line 93 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L93

Missing function or method docstring (missing-function-docstring)

Check notice on line 94 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L94

Trailing whitespace (trailing-whitespace)
sitesExtents = setSitesExtents(numQubits, bondDims)

Check notice on line 96 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L96

Trailing whitespace (trailing-whitespace)
MPS_example = []

Check notice on line 97 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L97

Redefining name 'MPS_example' from outer scope (line 123) (redefined-outer-name)

Check notice on line 98 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L98

Trailing whitespace (trailing-whitespace)
for T_shape in sitesExtents:

Check notice on line 100 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L100

Trailing whitespace (trailing-whitespace)
if T_shape[-1] == -1:
T_shape = T_shape[:-1]

Check notice on line 103 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L103

Trailing whitespace (trailing-whitespace)
MPS_site = np.random.rand(*(tuple(T_shape)))

Check notice on line 105 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L105

Trailing whitespace (trailing-whitespace)
MPS_example.append(MPS_site)

Check notice on line 107 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L107

Trailing whitespace (trailing-whitespace)
return MPS_example

if __name__ == "__main__":

wires = 4

Check notice on line 112 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L112

Trailing whitespace (trailing-whitespace)
bond_dims = [5,7,5]

MPS_example = create_MPS_with_custom_bondDims(wires, bond_dims)

Check notice on line 115 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L115

Trailing whitespace (trailing-whitespace)

method = "mps"

dev = qml.device("lightning.tensor", wires=wires, method=method, cutoff=1e-7, bond_dim=bond_dims)

Check notice on line 119 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L119

Trailing whitespace (trailing-whitespace)

dev_wires = dev.wires.tolist()

Check notice on line 122 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L122

Trailing whitespace (trailing-whitespace)
@qml.qnode(dev)
def circuit(custom_MPS=MPS_example):

Check notice on line 124 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L124

Trailing whitespace (trailing-whitespace)

qml.MPSPrep(mps=custom_MPS, wires=dev_wires)

Check notice on line 126 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L126

Trailing whitespace (trailing-whitespace)

return qml.expval(qml.PauliZ(0))

print("result",circuit())

Check notice on line 130 in 00_Playground/LT-mps_custom_bond_dim.py

View check run for this annotation

codefactor.io / CodeFactor

00_Playground/LT-mps_custom_bond_dim.py#L130

Trailing whitespace (trailing-whitespace)

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.41.0-dev20"
__version__ = "0.41.0-dev21"
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ class MPSTNCuda final : public TNCuda<Precision, MPSTNCuda<Precision>> {
const std::size_t maxBondDim)
: BaseType(numQubits, maxBondDim) {}

explicit MPSTNCuda(const std::size_t numQubits,
const std::size_t maxBondDim,
const std::vector<std::size_t> &bondDims)
: BaseType(numQubits, maxBondDim, bondDims) {}

explicit MPSTNCuda(const std::size_t numQubits,
const std::size_t maxBondDim, DevTag<int> dev_tag)
: BaseType(numQubits, dev_tag, maxBondDim) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ class TNCuda : public TNCudaBase<PrecisionT, Derived> {
// of cutensornet.
}

// Constructor with bondDims for custom MPS
explicit TNCuda(std::size_t numQubits, std::size_t maxBondDim,
const std::vector<std::size_t> &bondDims)
: BaseType(numQubits), maxBondDim_(maxBondDim), bondDims_(bondDims),
sitesModes_(setSitesModes_()), sitesExtents_(setSitesExtents_()),
sitesExtents_int64_(setSitesExtents_int64_()),
cublascaller_(make_shared_cublas_caller()),
gate_cache_(std::make_shared<TNCudaGateCache<PrecisionT>>(
BaseType::getDevTag())) {
initTensors_();
appendInitialMPSState_(
getSitesExtentsPtr()
.data()); // This API works for Exact Tensor Network as well,
// given sitesExtents_ settings meet the requirement
// of cutensornet.
}

explicit TNCuda(const std::size_t numQubits, DevTag<int> dev_tag,
const std::size_t maxBondDim = 1)
: BaseType(numQubits, dev_tag.getDeviceID(), dev_tag.getStreamID()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ void registerBackendClassSpecificBindingsMPS(PyClass &pyclass) {

pyclass
.def(py::init<std::size_t, std::size_t>()) // num_qubits, max_bond_dim
.def(py::init<std::size_t, std::size_t,
std::vector<std::size_t>>()) // num_qubits, max_bond_dim,
// list_bond_dim
.def(py::init<std::size_t, std::size_t,
DevTag<int>>()) // num_qubits, max_bond_dim, dev-tag
.def(
Expand Down Expand Up @@ -150,6 +153,25 @@ void registerBackendClassSpecificBindingsMPS(PyClass &pyclass) {
}

const auto &MPS_shape_dest = tensor_network.getSitesExtents();
// print MPS_shape_dest and MPS_shape_source
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// print MPS_shape_dest and MPS_shape_source


std::cout << "MPS_shape_dest: " << std::endl;
for (const auto &shape : MPS_shape_dest) {
for (const auto &dim : shape) {
std::cout << dim << " ";
}
std::cout << std::endl;
}

std::cout << "MPS_shape_source: " << std::endl;
for (const auto &shape : MPS_shape_source) {
for (const auto &dim : shape) {
std::cout << dim << " ";
}
std::cout << std::endl;
}
Comment on lines +158 to +172
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
std::cout << "MPS_shape_dest: " << std::endl;
for (const auto &shape : MPS_shape_dest) {
for (const auto &dim : shape) {
std::cout << dim << " ";
}
std::cout << std::endl;
}
std::cout << "MPS_shape_source: " << std::endl;
for (const auto &shape : MPS_shape_source) {
for (const auto &dim : shape) {
std::cout << dim << " ";
}
std::cout << std::endl;
}



MPSShapeCheck(MPS_shape_dest, MPS_shape_source);

for (std::size_t idx = 0; idx < tensors.size(); idx++) {
Expand Down
7 changes: 6 additions & 1 deletion pennylane_lightning/lightning_tensor/_tensornet.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@
self._max_bond_dim = kwargs.get("max_bond_dim", 128)
self._cutoff = kwargs.get("cutoff", 0)
self._cutoff_mode = kwargs.get("cutoff_mode", "abs")
self._tensornet = self._tensornet_dtype()(self._num_wires, self._max_bond_dim)
self._bond_dim = kwargs.get("bond_dim", None)

Check notice on line 179 in pennylane_lightning/lightning_tensor/_tensornet.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/lightning_tensor/_tensornet.py#L179

Trailing whitespace (trailing-whitespace)
if self._bond_dim is not None:
self._tensornet = self._tensornet_dtype()(self._num_wires, self._max_bond_dim, self._bond_dim)
else:
self._tensornet = self._tensornet_dtype()(self._num_wires, self._max_bond_dim)
elif self._method == "tn":
self._tensornet = self._tensornet_dtype()(self._num_wires)
else:
Expand Down
23 changes: 22 additions & 1 deletion pennylane_lightning/lightning_tensor/lightning_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def circuit(num_qubits):
# pylint: disable=too-many-instance-attributes

_device_options = {
"mps": ("backend", "max_bond_dim", "cutoff", "cutoff_mode"),
"mps": ("backend", "max_bond_dim", "cutoff", "cutoff_mode", "bond_dim"),
Copy link
Member

Choose a reason for hiding this comment

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

Would you please update the docstr to add the new arg?

"tn": ("backend"),
}

Expand Down Expand Up @@ -340,12 +340,15 @@ def __init__(
f"Unexpected argument: {arg} during initialization of the lightning.tensor device."
)

self._custom_MPS = False

if not accepted_backends(self._backend):
raise ValueError(f"Unsupported backend: {self._backend}")
if self._method == "mps":
self._max_bond_dim = kwargs.get("max_bond_dim", 128)
self._cutoff = kwargs.get("cutoff", 0)
self._cutoff_mode = kwargs.get("cutoff_mode", "abs")
self._bond_dim = kwargs.get("bond_dim", None)

if not isinstance(self._max_bond_dim, int) or self._max_bond_dim < 1:
raise ValueError("The maximum bond dimension must be an integer greater than 0.")
Expand All @@ -354,6 +357,13 @@ def __init__(
if self._cutoff_mode not in ["rel", "abs"]:
raise ValueError(f"Unsupported cutoff mode: {self._cutoff_mode}")

if self._bond_dim is not None:
Copy link
Member

Choose a reason for hiding this comment

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

looks good as long as it works for algo and product. it would be even better to late initialize TN object util MPSprep is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice idea, but I am afraid of the potential risk of skipping multiple safety checks because the only way to update the TN object until the call of qml.MPSPrep should be destroy the current MPS and then create a new one with the new bond dims 😕

self._custom_MPS = True
if not isinstance(self._bond_dim, list):
raise ValueError("The bond dimension must be specified as a list.")
if len(self._bond_dim) != self._num_wires - 1:
raise ValueError("The bond dimension list must have length equal to the number of wires - 1.")

@property
def name(self):
"""The name of the device."""
Expand Down Expand Up @@ -382,6 +392,17 @@ def c_dtype(self):
def _tensornet(self, num_wires):
"""Return the tensornet object."""
if self.method == "mps":
if self._custom_MPS:
return LightningTensorNet(
num_wires,
self._method,
self._c_dtype,
device_name=self.name,
max_bond_dim=self._max_bond_dim,
Copy link
Member

Choose a reason for hiding this comment

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

just wondering how max_bond_dim would work in the background if _bond_dim.

cutoff=self._cutoff,
cutoff_mode=self._cutoff_mode,
bond_dim=self._bond_dim,
)
return LightningTensorNet(
num_wires,
self._method,
Expand Down
Loading