.. _TN simulator: .. currentmodule:: cuquantum.cutensornet.experimental ************************ Tensor network simulator ************************ .. _TN simulator intro: Introduction ============ Starting from cuQuantum Python v24.08, we provide new APIs that enable Python users to easily leverage :ref:`cuTensorNet state APIs ` for tensor network simulation. These APIs are now available under the :mod:`cuquantum.cutensornet.experimental` module and may **be subject to change** in future releases. Please share your feedback with us on `NVIDIA/cuQuantum GitHub Discussions`_! The new set of APIs are centered around the :class:`~NetworkState` class and are designed to support the following groups of users: - **Quantum Computing Framework Users:** These users can directly initialize a tensor network state from quantum circuit objects such as :class:`cirq.Circuit` or :class:`qiskit.QuantumCircuit` via the :meth:`NetworkState.from_circuit` method. - **Tensor Network Framework Developers and Researchers:** These users can build any state of interest by applying tensor operators, matrix product operators (MPOs), and set initial state to a matrix product state (MPS). The methods involved here include :meth:`NetworkState.apply_tensor_operator`, :meth:`NetworkState.update_tensor_operator`, :meth:`NetworkState.set_initial_mps`, :meth:`NetworkState.apply_mpo`, and :meth:`NetworkState.apply_network_operator`. Ndarray-like objects from NumPy, CuPy, and PyTorch are all supported as input operands. .. _NVIDIA/cuQuantum GitHub Discussions: https://github.com/NVIDIA/cuQuantum/discussions .. note:: - The :class:`~NetworkState` class supports arbitrary state dimensions beyond regular quantum circuit states with qubits (``d=2``). An example of simulating a complex state with non-uniform state dimensions can be found in the `arbitrary state example`_. - For both MPS and MPO, only open boundary condition is supported. .. _arbitrary state example: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/experimental/network_state/generic_states/example02_arbitrary_dimension_numpy.py Users can further specify the tensor network simulation method as one of the following: - **Contraction-Based Simulations:** Specify ``config`` as a :class:`~TNConfig` object. - **MPS-Based Simulations:** Specify ``config`` as a :class:`~MPSConfig` object, offering detailed control over truncation extents, canonical centers, SVD algorithms, and normalization options. Once the problem is fully specified, users can take advantage of the following execution APIs to compute various properties: - :meth:`NetworkState.compute_state_vector`: Computes the final state coefficients as an N-dimensional tensor with extents matching the specified state. - :meth:`NetworkState.compute_amplitude`: Computes the amplitude coefficient for a given bitstring. - :meth:`NetworkState.compute_batched_amplitudes`: Computes the batched amplitude coefficients for a subset of state dimensions while others are fixed at certain states. - :meth:`NetworkState.compute_reduced_density_matrix`: Computes the reduced density matrix for a subset of state dimensions, optionally fixing another subset to specific states. - :meth:`NetworkState.compute_expectation`: Computes the expectation value for a given tensor network operator, which can be specified as a sum of tensor product (such as Pauli operators) or MPOs with coefficients. - :meth:`NetworkState.compute_sampling`: Draws samples from the underlying state, with options to sample just a subset of all state dimensions. - :meth:`NetworkState.compute_norm`: Computes the norm of the tensor network state. Additionally, the :class:`NetworkOperator` class allows users to create a network operator object as a sum of tensor products (via :meth:`NetworkOperator.append_product`) or MPOs (via :meth:`NetworkOperator.append_mpo`) with coefficients. This object can then interact with the :class:`NetworkState` class, enabling users to apply an MPO to the state or compute the expectation value of the operator on the state using methods like :meth:`NetworkState.apply_network_operator` and :meth:`NetworkState.compute_expectation`. .. _simulator caching: Caching feature =============== As of cuQuantum v24.08, the :class:`NetworkState` offers preliminary caching support for all execution methods with a ``compute_`` suffix **when contraction-based tensor network simulation or MPS simulation without value based truncation is used**. During the first call to these methods, the underlying cuTensorNet C object for these properties will be created, prepared, cached, and then executed to compute the final output. On subsequent calls to the **same method using compatible parameters** without updating the state with :meth:`NetworkState.apply_tensor_operator`, :meth:`NetworkState.apply_mpo`, :meth:`NetworkState.set_initial_mps`, or :meth:`NetworkState.apply_network_operator` (it's okay to call :meth:`NetworkState.update_tensor_operator`), the cached C object will be reused to compute the final output, thus reducing the overhead of C object creation and preparation. **Compatible parameters** have different contexts for different execution methods: - For :meth:`NetworkState.compute_state_vector`, :meth:`NetworkState.compute_amplitude`, and :meth:`NetworkState.compute_norm`, any parameters will result in using the same cached object. - For :meth:`NetworkState.compute_batched_amplitudes`, the set of state dimensions specified by ``fixed`` must be identical while the fixed state for each dimension may differ. - For :meth:`NetworkState.compute_reduced_density_matrix`, the ``where`` parameter and the set of state dimensions specified by ``fixed`` must be identical while the fixed state for each dimension may differ. - For :meth:`NetworkState.compute_expectation`, the same :class:`NetworkOperator` object with unchanged underlying components must be used. Providing ``operators`` as a string of Pauli operators or as a dictionary mapping Pauli strings to coefficients will **not** activate the caching mechanism. - For :meth:`NetworkState.compute_sampling`, the same ``modes`` parameter is required to activate the caching mechanism. For more details, please refer to our `cirq caching example`_ and `qiskit caching example`_. Additionally, users can leverage the caching feature along with the :meth:`NetworkState.update_tensor_operator` method to reduce the overhead for variational workflows where the same computation needs to be performed on numerous states with identical topologies. For more details, please refer to our `variational workflow example`_. .. _cirq caching example: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/experimental/network_state/circuits_cirq/example04_caching.py .. _qiskit caching example: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/experimental/network_state/circuits_qiskit/example04_caching.py .. _variational workflow example: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/experimental/network_state/generic_states/example04_variational_expectation.py .. _simulator mpi: MPI support =========== As of cuQuantum v24.08, the :class:`NetworkState` offers preliminary distributed parallel support for all execution methods with a ``compute_`` suffix **when contraction-based tensor network simulation is used**, i.e., :class:`TNConfig`. To activate distributed parallel execution, users must perform the following tasks: 1. Explicitly set the device ID to use in :attr:`cuquantum.NetworkOptions.device_id` and provide it to :class:`NetworkState` via the ``options`` parameter. 2. Explicitly create the library handle on the corresponding device using :func:`cuquantum.cutensornet.create`, bind an MPI communicator to the library handle using :func:`cuquantum.cutensornet.distributed_reset_configuration`, and provide it to :class:`NetworkState` via the ``options`` parameter. For more details, please refer to our `cirq mpi sampling example`_ and `qiskit mpi sampling example`_. .. _cirq mpi sampling example: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/experimental/network_state/circuits_cirq/example07_mpi_sampling.py .. _qiskit mpi sampling example: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/experimental/network_state/circuits_qiskit/example07_mpi_sampling.py