From 1cb00b38f6048e14a61e47e615e545014ecdf028 Mon Sep 17 00:00:00 2001 From: PabloAndresCQ Date: Fri, 8 Sep 2023 13:31:59 +0100 Subject: [PATCH 1/3] Updated changelog for v0.3.0. --- _metadata.py | 2 +- docs/changelog.rst | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/_metadata.py b/_metadata.py index 62f9f6f8..b3cb0440 100644 --- a/_metadata.py +++ b/_metadata.py @@ -1,2 +1,2 @@ -__extension_version__ = "0.2.1" +__extension_version__ = "0.3.0" __extension_name__ = "pytket-cutensornet" diff --git a/docs/changelog.rst b/docs/changelog.rst index 9aab3ad4..6066ea60 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,13 @@ Changelog ~~~~~~~~~ +0.3.0 (September 2023) +---------------------- + +* Added MPS sampling feature. +* Refactored MPS module for better maintainability and extendability. +* ``Tensor`` class removed from the API since it is no longer necessary. + 0.2.1 (August 2023) ------------------- @@ -16,4 +23,4 @@ Changelog 0.1.0 (June 2023) ----------------- -* Initial implementation of the converter and backend modules for use on a single GPU. \ No newline at end of file +* Initial implementation of the converter and backend modules for use on a single GPU. From ebe0539a09be0007c330a5b5280ccdf4deda69bd Mon Sep 17 00:00:00 2001 From: Iakov Polyak Date: Wed, 20 Sep 2023 11:41:56 +0100 Subject: [PATCH 2/3] Some mypy fixes. --- pytket/extensions/cutensornet/tensor_network_convert.py | 2 +- tests/test_tensor_network_convert.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pytket/extensions/cutensornet/tensor_network_convert.py b/pytket/extensions/cutensornet/tensor_network_convert.py index ef2c919b..f5bb7468 100644 --- a/pytket/extensions/cutensornet/tensor_network_convert.py +++ b/pytket/extensions/cutensornet/tensor_network_convert.py @@ -152,7 +152,7 @@ def _get_gate_tensors(self, adj: bool = False) -> DefaultDict[Any, List[Any]]: self._logger.debug(f"Adding unitary: \n {com.op.get_unitary()}") # Add a unitary for a gate pointing "upwards" (e.g. CX[1, 0]) if com.op.n_qubits > 1: - com_qix = [self._circuit.qubits.index(qb) for qb in com.args] + com_qix = [self._circuit.qubits.index(qb) for qb in com.qubits] self._logger.debug(f"command qubit indices: {com_qix}") com_qix_compressed = [i for i, _ in enumerate(com_qix)] self._logger.debug( diff --git a/tests/test_tensor_network_convert.py b/tests/test_tensor_network_convert.py index 0a361e4e..f6d09a03 100644 --- a/tests/test_tensor_network_convert.py +++ b/tests/test_tensor_network_convert.py @@ -79,8 +79,8 @@ def test_toffoli_box_with_implicit_swaps() -> None: ket_circ = Circuit(3) # Create the circuit - ket_circ.add_toffolibox(ToffoliBox(perm), [Qubit(0), Qubit(1)]) - ket_circ.add_toffolibox(ToffoliBox(perm), [Qubit(1), Qubit(2)]) + ket_circ.add_toffolibox(ToffoliBox(perm), [Qubit(0), Qubit(1)]) # type: ignore + ket_circ.add_toffolibox(ToffoliBox(perm), [Qubit(1), Qubit(2)]) # type: ignore DecomposeBoxes().apply(ket_circ) CnXPairwiseDecomposition().apply(ket_circ) @@ -116,7 +116,7 @@ def to_bool_tuple(n_qubits: int, x: int) -> tuple: perm[to_bool_tuple(n_qubits, orig)] = to_bool_tuple(n_qubits, dest) # Create a circuit implementing the permutation above - ket_circ = ToffoliBox(perm).get_circuit() + ket_circ = ToffoliBox(perm).get_circuit() # type: ignore DecomposeBoxes().apply(ket_circ) CnXPairwiseDecomposition().apply(ket_circ) From ba23446268aaaba79fd1e7a08191f229697734d4 Mon Sep 17 00:00:00 2001 From: Pablo Andres-Martinez Date: Fri, 22 Sep 2023 06:46:31 -0700 Subject: [PATCH 3/3] More mypy fixes. --- pytket/extensions/cutensornet/mps/mps.py | 4 ++-- pytket/extensions/cutensornet/mps/mps_gate.py | 2 +- pytket/extensions/cutensornet/mps/mps_mpo.py | 2 +- pytket/extensions/cutensornet/mps/simulation.py | 17 +++++++++++------ tests/conftest.py | 7 ++++--- tests/test_mps.py | 4 ++-- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/pytket/extensions/cutensornet/mps/mps.py b/pytket/extensions/cutensornet/mps/mps.py index c0f6c70f..3514815b 100644 --- a/pytket/extensions/cutensornet/mps/mps.py +++ b/pytket/extensions/cutensornet/mps/mps.py @@ -30,8 +30,8 @@ except ImportError: warnings.warn("local settings failed to import cutensornet", ImportWarning) -from pytket.circuit import Command, Op, OpType, Qubit # type: ignore -from pytket.pauli import Pauli, QubitPauliString # type: ignore +from pytket.circuit import Command, Op, OpType, Qubit +from pytket.pauli import Pauli, QubitPauliString # An alias so that `intptr_t` from CuQuantum's API (which is not available in # base python) has some meaningful type name. diff --git a/pytket/extensions/cutensornet/mps/mps_gate.py b/pytket/extensions/cutensornet/mps/mps_gate.py index b929284b..3c522afd 100644 --- a/pytket/extensions/cutensornet/mps/mps_gate.py +++ b/pytket/extensions/cutensornet/mps/mps_gate.py @@ -26,7 +26,7 @@ except ImportError: warnings.warn("local settings failed to import cutensornet", ImportWarning) -from pytket.circuit import Op # type: ignore +from pytket.circuit import Op from .mps import MPS diff --git a/pytket/extensions/cutensornet/mps/mps_mpo.py b/pytket/extensions/cutensornet/mps/mps_mpo.py index 937e2db4..42f82462 100644 --- a/pytket/extensions/cutensornet/mps/mps_mpo.py +++ b/pytket/extensions/cutensornet/mps/mps_mpo.py @@ -28,7 +28,7 @@ except ImportError: warnings.warn("local settings failed to import cutensornet", ImportWarning) -from pytket.circuit import Op, Qubit # type: ignore +from pytket.circuit import Op, Qubit from .mps import ( CuTensorNetHandle, DirectionMPS, diff --git a/pytket/extensions/cutensornet/mps/simulation.py b/pytket/extensions/cutensornet/mps/simulation.py index 128e2fe5..a9224407 100644 --- a/pytket/extensions/cutensornet/mps/simulation.py +++ b/pytket/extensions/cutensornet/mps/simulation.py @@ -4,11 +4,11 @@ from collections import defaultdict # type: ignore import numpy as np # type: ignore -from pytket.circuit import Circuit, Command, Qubit # type: ignore -from pytket.transform import Transform # type: ignore -from pytket.architecture import Architecture # type: ignore -from pytket.passes import DefaultMappingPass # type: ignore -from pytket.predicates import CompilationUnit # type: ignore +from pytket.circuit import Circuit, Command, Qubit +from pytket.transform import Transform +from pytket.architecture import Architecture +from pytket.passes import DefaultMappingPass +from pytket.predicates import CompilationUnit from .mps import CuTensorNetHandle, MPS from .mps_gate import MPSxGate @@ -120,7 +120,11 @@ def prepare_circuit(circuit: Circuit) -> tuple[Circuit, dict[Qubit, Qubit]]: prep_circ = cu.circuit Transform.DecomposeBRIDGE().apply(prep_circ) - qubit_map = {arch_q: orig_q for orig_q, arch_q in cu.final_map.items()} + qubit_map: dict[Qubit, Qubit] = {} + for orig_q, arch_q in cu.final_map.items(): + assert isinstance(orig_q, Qubit) + assert isinstance(arch_q, Qubit) + qubit_map[arch_q] = orig_q return (prep_circ, qubit_map) @@ -190,6 +194,7 @@ def _get_sorted_gates(circuit: Circuit) -> list[Command]: "nearest neighbour qubits. Consider using prepare_circuit().", ) elif left_distance is None: + assert right_distance is not None current_qubit = circuit.qubits[q_index + right_distance] elif right_distance is None: current_qubit = circuit.qubits[q_index - left_distance] diff --git a/tests/conftest.py b/tests/conftest.py index 66d1e2a1..32ae62c2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,8 @@ import pytest import numpy as np from scipy.stats import unitary_group # type: ignore -from pytket.circuit import Circuit, OpType, Unitary2qBox # type: ignore -from pytket.passes import DecomposeBoxes # type: ignore +from pytket.circuit import Circuit, OpType, Unitary2qBox +from pytket.passes import DecomposeBoxes def random_line_circuit(n_qubits: int, layers: int) -> Circuit: @@ -21,7 +21,8 @@ def random_line_circuit(n_qubits: int, layers: int) -> Circuit: ] # Direction of each CX gate is random for pair in qubit_pairs: - np.random.shuffle(pair) + if np.random.rand() > 0.5: + pair = [pair[1], pair[0]] for pair in qubit_pairs: c.CX(pair[0], pair[1]) diff --git a/tests/test_mps.py b/tests/test_mps.py index 50b0ba39..c8f8f440 100644 --- a/tests/test_mps.py +++ b/tests/test_mps.py @@ -327,13 +327,13 @@ def test_circ_approx_explicit(circuit: Circuit) -> None: # Fixed virtual bond dimension # Check for MPSxGate mps_gate = simulate(libhandle, circuit, ContractionAlg.MPSxGate, chi=8) - assert np.isclose(mps_gate.fidelity, 0.05, atol=1e-2) + assert np.isclose(mps_gate.fidelity, 0.03, atol=1e-2) assert mps_gate.is_valid() assert np.isclose(mps_gate.vdot(mps_gate), 1.0, atol=mps_gate._atol) # Check for MPSxMPO mps_mpo = simulate(libhandle, circuit, ContractionAlg.MPSxMPO, chi=8) - assert np.isclose(mps_mpo.fidelity, 0.09, atol=1e-2) + assert np.isclose(mps_mpo.fidelity, 0.06, atol=1e-2) assert mps_mpo.is_valid() assert np.isclose(mps_mpo.vdot(mps_mpo), 1.0, atol=mps_mpo._atol)