Circuit to tensor network converter

Introduction

Starting cuQuantum Python v22.07, we provide a CircuitToEinsum converter that takes either a qiskit.QuantumCircuit or a cirq.Circuit and generates the corresponding tensor network contraction for the target operation. The goal of the converter is to allow Qiskit and Cirq users to easily explore the functionalities of the cuTensorNet library. As mentioned in the tensor network introduction, quantum circuits can be viewed as tensor networks. For any quantum circuit, CircuitToEinsum can construct the corresponding tensor network to compute various quantities of interest. The output tensor network is returned as an Einstein summation expression with tensor operands.

We support the following operations:

  • state_vector(): The contraction of this Einstein summation expression yields the final state coefficients as an N-dimensional tensor where N is the number of qubits in the circuit. The mode labels of the tensor correspond to the CircuitToEinsum.qubits.

  • amplitude(): The contraction of this Einstein summation expression yields the amplitude coefficient for a given bitstring.

  • batched_amplitudes(): The contraction of this Einstein summation expression yields the amplitude coefficients for a subset of qubits while the others are fixed at certain states.

  • reduced_density_matrix(): The contraction of this Einstein summation expression yields the reduced density matrix for a subset of qubits, optionally with another subset of qubits set to a fixed state.

  • expectation(): The contraction of this Einstein summation expression yields the expectation value for a given Pauli string.

The CircuitToEinsum class also allows user to specify a desired tensor backend (cupy, torch, numpy) via the backend argument when constructing the converter object. The returned Einstein summation expression and tensor operands can then directly serve as the input arguments for cuquantum.contract() or the corresponding backend’s einsum function.

Usage example

import cirq
import cupy

from cuquantum import contract, CircuitToEinsum

# create a random cirq.Circuit
circuit = cirq.testing.random_circuit(qubits=4, n_moments=4, op_density=0.9, random_state=1)
# same task can be achieved with qiskit.circuit.random.random_circuit

# construct the CircuitToEinsum converter targeting double precision and cupy operands
converter = CircuitToEinsum(circuit, dtype='complex128', backend='cupy')

# generate the Einstein summation expression and tensor operands for computing the amplitude coefficient of bitstring 0000
expression, operands = converter.amplitude(bitstring='0000')
assert all([isinstance(op, cupy.ndarray) for op in operands])

# contract the network to compute the amplitude
amplitude = contract(expression, *operands)
amplitude_cupy = cupy.einsum(expression, *operands)
assert cupy.allclose(amplitude, amplitude_cupy)

Multiple Jupyter notebooks are available for Cirq and Qiskit users to easily build up their tensor network based simulations using cuTensorNet.