Limitations in qubit numbers in "default.mixed" device

Hi, I wanted to know if there is a limitation in number of qubits in “default.mixed” device. As I try to create a device with 17 qubits I get an error, but when I try 16 or lower or when I change the device to “default.qubit” it seems to work with no problems.

dev = qml.device("default.mixed", wires=range(17))

Here is the error:

ValueError                                Traceback (most recent call last)
<ipython-input-95-b3946235d6d5> in <cell line: 1>()
----> 1 dev = qml.device("default.mixed", wires=range(17))

6 frames
/usr/local/lib/python3.10/dist-packages/pennylane/devices/device_constructor.py in device(name, *args, **kwargs)
    261 
    262         # Construct the device
--> 263         dev = plugin_device_class(*args, **options)
    264 
    265         # Once the device is constructed, we set its custom expansion function if

/usr/local/lib/python3.10/dist-packages/pennylane/logging/decorators.py in wrapper_exit(*args, **kwargs)
     63     @wraps(func)
     64     def wrapper_exit(*args, **kwargs):
---> 65         output = func(*args, **kwargs)
     66         if lgr.isEnabledFor(log_level):  # pragma: no cover
     67             f_string = _get_bound_signature(*args, **kwargs)

/usr/local/lib/python3.10/dist-packages/pennylane/devices/default_mixed.py in __init__(self, wires, r_dtype, c_dtype, shots, analytic, readout_prob)
    219 
    220         # Create the initial state.
--> 221         self._state = self._create_basis_state(0)
    222         self._pre_rotated_state = self._state
    223         self.measured_wires = []

/usr/local/lib/python3.10/dist-packages/pennylane/devices/default_mixed.py in _create_basis_state(self, index)
    237         rho = qnp.zeros((2**self.num_wires, 2**self.num_wires), dtype=self.C_DTYPE)
    238         rho[index, index] = 1
--> 239         return qnp.reshape(rho, [2] * (2 * self.num_wires))
    240 
    241     @classmethod

/usr/local/lib/python3.10/dist-packages/autoray/autoray.py in do(fn, like, *args, **kwargs)
     79     backend = _choose_backend(fn, args, kwargs, like=like)
     80     func = get_lib_fn(backend, fn)
---> 81     return func(*args, **kwargs)
     82 
     83 

/usr/local/lib/python3.10/dist-packages/numpy/core/fromnumeric.py in reshape(a, newshape, order)
    283            [5, 6]])
    284     """
--> 285     return _wrapfunc(a, 'reshape', newshape, order=order)
    286 
    287 

/usr/local/lib/python3.10/dist-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
     57 
     58     try:
---> 59         return bound(*args, **kwds)
     60     except TypeError:
     61         # A TypeError occurs if the object does have such a method in its

ValueError: maximum supported dimension for an ndarray is 32, found 34

and the qml.about() results:

Name: PennyLane
Version: 0.39.0
Summary: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Home-page: GitHub - PennyLaneAI/pennylane: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Author:
Author-email:
License: Apache License 2.0
Location: /usr/local/lib/python3.10/dist-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, packaging, pennylane-lightning, requests, rustworkx, scipy, toml, typing-extensions
Required-by: PennyLane_Lightning
Platform info: Linux-6.1.85±x86_64-with-glibc2.35
Python version: 3.10.12
Numpy version: 1.26.4
Scipy version: 1.13.1
Installed devices:

  • default.clifford (PennyLane-0.39.0)
  • default.gaussian (PennyLane-0.39.0)
  • default.mixed (PennyLane-0.39.0)
  • default.qubit (PennyLane-0.39.0)
  • default.qutrit (PennyLane-0.39.0)
  • default.qutrit.mixed (PennyLane-0.39.0)
  • default.tensor (PennyLane-0.39.0)
  • null.qubit (PennyLane-0.39.0)
  • reference.qubit (PennyLane-0.39.0)
  • lightning.qubit (PennyLane_Lightning-0.39.0)

Seems like it’s a problem of ndarray, as other people have encountered this error in other scenarios with ndarray, but the suggestions include changing the dimensions or have the array in a flat form.
But as it is an internal function in the Pennylane, I don’t think I can do that.
Can you tell me how can I work around this error and create a mixed device with 17 qubits?

Hi @Amir_Kermanshahani , welcome to the Forum!

default.mixed uses density matrices, which require a lot of memory to store quantum states. The error that you’re seeing arises because 17 qubits is too large for most simulations, meaning that most likely you’ll run out of memory in your computer.

I’m assuming you want to perform simulations with noise, right? If that’s the case then unfortunately there’s not much you can do. If you don’t need noisy simulations then I’d recommend using lightning.qubit instead.

Let me know if this answers your question.

Thanks for your welcome, happy to be part of the community!

That’s right, I have developed and tested my program which includes 17 qubits using the “default.qubit” device and everything was fine. Now I wanted to test my program in a noisy environment to see how the results would differ.

As my circuit uses all the 17 qubits at the same iteration, I don’t think I can break it up or do it in multiple steps.

Any suggestions or workarounds? Isn’t there a way to overcome this limitation in a 64-bit system or on a cloud environment? I didn’t know of this limitation and that’s sad that noisy simulations can’t be done with more than 16 qubits. :frowning:

@Amir_Kermanshahani One idea could be to use circuit cutting. It’s used when you need to break up your circuits into smaller sub-circuits.

You can learn more about it here in the docs.

I did a quick test with default.mixed and got no errors so it seems to work. If you’re using the auto-cutter all you need to do is add one line of code (the circuit-cutting transform) right above your QNode definition, and define a device with less qubits than your circuit requires. Eg. define a device with 16 qubits even if you use 17.

from functools import partial
dev = qml.device("default.mixed", wires=2)

@partial(qml.cut_circuit, auto_cutter=True)
@qml.qnode(dev)

Some things to note:

  • Only circuits that return a single expectation value are supported.
  • The auto_cutter option requires KaHyPar to be installed. You can pip install kahypar for Linux and Mac, or visit the instructions here to compile from source for Windows.
  • There will be classical overheads, meaning that your overall runtime might be slower (but at least it allows you to run something).
  • If you define a device that’s too small but want to run a very large circuit on it this may cause too much overhead and it may not work (eg. defining a 2-qubit device for running a 17-qubit circuit).

Let me know if this works for you!

1 Like

Thanks for your detailed explanation. That’s a nice feature I wasn’t familiar with.

Unfortunately, my circuit returns an array of values instead of a single expectation value so it doesn’t consent to the first note you mentioned. Additionally it entangles 16 of 17 qubits by controlled gates and measures them at the same time.

I don’t think it’s a good approach for my circuit. I try to find a workaround by reducing the number of qubits used in my circuit so that I can use the “default.mixed” device to introduce noise into my system.

Thanks for your help, appreciate it.

Oh that’s unfortunate @Amir_Kermanshahani .

If your circuit is chemistry-related you could use techniques such as qubit tapering to lower your number of qubits.

In any case, I’m glad you now know about circuit cutting, it can be a powerful tool for the future.

1 Like