Added comments and refactor codes

This commit is contained in:
tankya2
2023-04-19 16:28:05 +08:00
parent aee995802f
commit e849e6926b

View File

@@ -3,31 +3,50 @@ import numpy as np
class QiboCircuitToEinsum:
"""This class takes a quantum circuit defined in Qibo (i.e. a Circuit object)
and convert it to an equivalent Tensor Network (TN) representation that is formatted for
cuQuantum' contract method to compute the state vectors.
See document for detail: https://docs.nvidia.com/cuda/cuquantum/python/api/generated/cuquantum.contract.html
When the class is constructed, it first process the circuit to an intermediate form by extracting the gate matrix
and grouping each gate with its corresponding qubit it is acting on to a list.
It is then converted it to an equivalent TN expression following the Einstein
summation convention through the class function state_vector_operand().
The output is to be used by cuQuantum's contract() for computation of the state vectors of the circuit.
"""
def __init__(self, circuit, dtype="complex128"):
def op_shape_from_qubits(nqubits):
"""This function is to modify the shape of the tensor to the required format by cuQuantum
(qubit_states,) * input_output * qubits_involved
"""
return (2,) * 2 * nqubits
self.backend = cp
self.dtype = getattr(self.backend, dtype)
self.input_tensor_counter = np.zeros((circuit.nqubits,))
self.gate_tensors = []
gates_qubits = []
for gate in circuit.queue:
for target in gate.target_qubits:
self.input_tensor_counter[target] += 1
for control in gate.control_qubits:
self.input_tensor_counter[control] += 1
gate_qubits = gate.control_qubits + gate.target_qubits
gates_qubits.extend(gate_qubits)
# self.gate_tensors is to extract into a list the gate matrix together with the qubit id that it is acting on
# https://github.com/NVIDIA/cuQuantum/blob/6b6339358f859ea930907b79854b90b2db71ab92/python/cuquantum/cutensornet/_internal/circuit_parser_utils_cirq.py#L32
required_shape = op_shape_from_qubits(len(gate_qubits))
self.gate_tensors.append(
(
cp.asarray(gate.matrix).reshape((2,) * 2 * len(gate_qubits)),
cp.asarray(gate.matrix).reshape(required_shape),
gate_qubits,
)
)
# self.active_qubits is to identify qubits with at least 1 gate acting on it in the whole circuit.
self.active_qubits = [
indx for indx, value in enumerate(self.input_tensor_counter) if value > 0
]
def state_vector(self):
# self.active_qubits is to identify qubits with at least 1 gate acting on it in the whole circuit.
self.active_qubits = np.unique(gates_qubits)
def state_vector_operands(self):
input_tensor_count = len(self.active_qubits)
input_operands = self._get_bitstring_tensors(