New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] too many subscripts in einsum with 8 qubits (default.mixed) #3582
Comments
This seems to be a particular issue with (Note that |
So the actual limit for this device is seven qubits when you have gates which have not been decomposed further? |
I'm not completely sure what the limit is, it might depend on the combination of device wire count and operation wire count. I built a naive implementation based on def _apply_channel_tensordot(self, kraus, wires):
r"""Apply a quantum channel specified by a list of Kraus operators to subsystems of the
quantum state. For a unitary gate, there is a single Kraus operator. Implementation
based on `tensordot` instead of `einsum`.
Args:
kraus (list[array]): Kraus operators
wires (Wires): target wires
"""
channel_wires = self.map_wires(wires)
rho_dim = 2 * self.num_wires
num_ch_wires = len(channel_wires)
# Computes K^\dagger, needed for the transformation K \rho K^\dagger
kraus_dagger = [qnp.conj(qnp.transpose(k)) for k in kraus]
kraus = qnp.stack(kraus)
kraus_dagger = qnp.stack(kraus_dagger)
# Shape kraus operators
kraus_shape = [len(kraus)] + [2] * (num_ch_wires * 2)
kraus = qnp.cast(qnp.reshape(kraus, kraus_shape), dtype=self.C_DTYPE)
kraus_dagger = qnp.cast(qnp.reshape(kraus_dagger, kraus_shape), dtype=self.C_DTYPE)
# row indices of the quantum state affected by this operation
row_wires_list = channel_wires.tolist()
# column indices are shifted by the number of wires
col_wires_list = [w + self.num_wires for w in row_wires_list]
axes_left = [list(range(num_ch_wires, 2 * num_ch_wires)), row_wires_list]
axes_right = [col_wires_list, list(range(num_ch_wires))]
source = list(range(-num_ch_wires, 0))
dest = col_wires_list
self._state = qnp.sum([
qnp.tensordot(qnp.tensordot(k, self._state, axes_left), k_d, axes_right)
for k, k_d in zip(kraus, kraus_dagger)
],
axis=0,
)
self._state = qnp.moveaxis(self._state, source, dest) It passes the existing tests for |
I tried this implementation, and the circuits execute with higher qubit counts. But, the results for some circuits are incorrect and do not match the original implementation.
After ironing out the bugs and testing for performance, this can be a solution. |
Ah, that's right. I forgot to permute the axes corresponding to the row indices of the density matrix. |
@ankit27kh If you are interested, take a look at the linked PR and the fixed prototype. |
Expected behavior
The circuit runs without any error.
Actual behavior
Execution fails with error:
Additional information
It is mentioned here #807 (comment) that the device can handle 23 qubits before encountering this error. This also forms the basis of this error:
But, the execution fails with some circuits using just 8 qubits.
A simple example is given below.
Source code
Tracebacks
No response
System information
Existing GitHub issues
The text was updated successfully, but these errors were encountered: