diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index ad0271b5cf..7b591fe79b 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -49,6 +49,9 @@ ### Improvements +* Update the `lightning.tensor` Python layer unit tests, as `lightning.tensor` cannot be cleaned up like other state-vector devices because the data is attached to the graph. It is recommended to use one device per circuit for `lightning.tensor`. + [(#971)](https://github.com/PennyLaneAI/pennylane-lightning/pull/971) + * Fix PTM stable-latest. [(#961)](https://github.com/PennyLaneAI/pennylane-lightning/pull/961) @@ -129,6 +132,9 @@ ### Documentation +* Update `lightning.tensor` usage suggestions. + [(#971)](https://github.com/PennyLaneAI/pennylane-lightning/pull/971) + * Update ``lightning.tensor`` documentation to include all the new features added since pull request #756. The new features are: 1, Finite-shot measurements; 2. Expval-base quantities; 3. Support for ``qml.state()`` and ``qml.stateprep()``; 4. Support for all gates support via Matrix Product Operator (MPO). [(#909)](https://github.com/PennyLaneAI/pennylane-lightning/pull/909) diff --git a/doc/lightning_tensor/device.rst b/doc/lightning_tensor/device.rst index cf125c07cc..7a364f0245 100644 --- a/doc/lightning_tensor/device.rst +++ b/doc/lightning_tensor/device.rst @@ -53,6 +53,7 @@ Check out the :doc:`/lightning_tensor/installation` guide for more information. .. seealso:: `DefaultTensor `__ for a CPU only tensor network simulator device. +Note that as `lightning.tensor` cannot be cleaned up like other state-vector devices because the data is attached to the graph. It is recommended to create a new ``lightning.tensor`` device per circuit to ensure resources are correctly handled. Operations and observables support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/test_gates.py b/tests/test_gates.py index da414c3789..c3d361836c 100644 --- a/tests/test_gates.py +++ b/tests/test_gates.py @@ -104,7 +104,7 @@ def test_gate_unitary_correct(op, op_name): if op_name == "QubitUnitary" and device_name == "lightning.tensor": pytest.skip( - "Skipping QubitUnitary on lightning.tensor. It can't be decomposed into 1-wire or 2-wire gates" + "Skipping QubitUnitary on lightning.tensor. as `lightning.tensor` cannot be cleaned up like other state-vector devices because the data is attached to the graph. It is recommended to use one device per circuit for `lightning.tensor`." ) dev = qml.device(device_name, wires=wires) @@ -153,6 +153,40 @@ def output(input): assert np.allclose(unitary, unitary_expected) +@pytest.mark.parametrize("op_name", ld.operations) +def test_gate_unitary_correct_lt(op, op_name): + """Test if lightning device correctly applies gates by reconstructing the unitary matrix and + comparing to the expected version""" + + if op_name in ("BasisState", "QubitStateVector", "StatePrep"): + pytest.skip("Skipping operation because it is a state preparation") + if op == None: + pytest.skip("Skipping operation.") + + wires = len(op[2]["wires"]) + + if wires == 1 and device_name == "lightning.tensor": + pytest.skip("Skipping single wire device on lightning.tensor.") + + unitary = np.zeros((2**wires, 2**wires), dtype=np.complex128) + + for i, input in enumerate(itertools.product([0, 1], repeat=wires)): + dev = qml.device(device_name, wires=wires) + + @qml.qnode(dev) + def output(input): + qml.BasisState(input, wires=range(wires)) + op[0](*op[1], **op[2]) + return qml.state() + + out = output(np.array(input)) + unitary[:, i] = out + + unitary_expected = qml.matrix(op[0](*op[1], **op[2])) + + assert np.allclose(unitary, unitary_expected) + + @pytest.mark.parametrize("op_name", ld.operations) def test_inverse_unitary_correct(op, op_name): """Test if lightning device correctly applies inverse gates by reconstructing the unitary matrix