Qml.device error with qiskit.aer

After creating a conda python 3.9 environment and activating it
I ran the following command:

pip3 install -r tutorial_requirements.txt

from the following page:

The I ran the following code and got the error as shown.

import pennylane as qml

import qiskit
import pennylane as qml
from pennylane import numpy as np

dev = qml.device('qiskit.aer',wires=2, shots=10)

@qml.qnode(dev)
def circuit(w):
    qml.Hadamard(wires=0)
    qml.RX(w,wires=0)
    return qml.expval(qml.PauliZ(0))

w=np.array(0.1,requires_grad=True)

opt = qml.GradientDescentOptimizer(stepsize=0.1)
w, cost = opt.step_and_cost(circuit, w)
print(cost)

Error message:

Traceback (most recent call last):
  File "/media/xxx/C-UAS-DB1/QuFI/test_aer.py", line 8, in <module>
    dev = qml.device('qiskit.aer',wires=2, shots=10)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages/pennylane/__init__.py", line 338, in device
    raise DeviceError("Device does not exist. Make sure the required plugin is installed.")
pennylane._device.DeviceError: Device does not exist. Make sure the required plugin is installed.
>>> qml.about()
Name: PennyLane
Version: 0.30.0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml
Required-by: PennyLane-Lightning

Platform info:           Linux-5.4.0-150-generic-x86_64-with-glibc2.27
Python version:          3.9.19
Numpy version:           1.23.5
Scipy version:           1.10.1
Installed devices:
- default.gaussian (PennyLane-0.30.0)
- default.mixed (PennyLane-0.30.0)
- default.qubit (PennyLane-0.30.0)
- default.qubit.autograd (PennyLane-0.30.0)
- default.qubit.jax (PennyLane-0.30.0)
- default.qubit.tf (PennyLane-0.30.0)
- default.qubit.torch (PennyLane-0.30.0)
- default.qutrit (PennyLane-0.30.0)
- null.qubit (PennyLane-0.30.0)
- lightning.qubit (PennyLane-Lightning-0.30.0)

I also get the same error when I run the run_circuits.py script from the github page. What could be the issue here?

Hi @art, it looks like you need to install the PennyLane-Qiskit plugin.

You can run pip install pennylane-qiskit. However I’m not sure what version you will need since you’re using an older version of PennyLane and Qiskit.

You can try running pip install PennyLane-qiskit==0.30.0 and then try setting the version of Qiskit according to the error message that you get.

If you’re interested in running the snippet of code you shared with the latest version of everything then I recommend that you wait until Tuesday when we will have a new PennyLane release. Then you can run pip install --upgrade pennylane pennylane-qiskit

If you don’t want to wait then you can install PennyLane and the Qiskit plugin from source with the following code:

pip install git+https://github.com/PennyLaneAI/pennylane.git#egg=pennylane
pip install git+https://github.com/PennyLaneAI/pennylane-qiskit.git

I hope this helps you

I did the last two pip installs. Now the code snippet runs but
run_circuits.py gives the following error:


Traceback (most recent call last):
  File "/media/xxx/C-UAS-DB1/QuFI/run_circuits.py", line 3, in <module>
    from qiskit.providers.fake_provider import FakeSantiago
ImportError: cannot import name 'FakeSantiago' from 'qiskit.providers.fake_provider' (/home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages/qiskit/providers/fake_provider/__init__.py)

>>> qml.about()
Name: PennyLane
Version: 0.37.0.dev0
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: https://github.com/PennyLaneAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-qiskit, PennyLane_Lightning

Platform info:           Linux-5.4.0-150-generic-x86_64-with-glibc2.27
Python version:          3.9.19
Numpy version:           1.26.4
Scipy version:           1.13.0
Installed devices:
- default.clifford (PennyLane-0.37.0.dev0)
- default.gaussian (PennyLane-0.37.0.dev0)
- default.mixed (PennyLane-0.37.0.dev0)
- default.qubit (PennyLane-0.37.0.dev0)
- default.qubit.autograd (PennyLane-0.37.0.dev0)
- default.qubit.jax (PennyLane-0.37.0.dev0)
- default.qubit.legacy (PennyLane-0.37.0.dev0)
- default.qubit.tf (PennyLane-0.37.0.dev0)
- default.qubit.torch (PennyLane-0.37.0.dev0)
- default.qutrit (PennyLane-0.37.0.dev0)
- default.qutrit.mixed (PennyLane-0.37.0.dev0)
- null.qubit (PennyLane-0.37.0.dev0)
- lightning.qubit (PennyLane-Lightning-0.35.1)
- qiskit.aer (PennyLane-qiskit-0.36.0)
- qiskit.basicaer (PennyLane-qiskit-0.36.0)
- qiskit.basicsim (PennyLane-qiskit-0.36.0)
- qiskit.ibmq (PennyLane-qiskit-0.36.0)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.36.0)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.36.0)
- qiskit.remote (PennyLane-qiskit-0.36.0)

Hi @art ,

It seems that Qiskit has changed their functionality and removed the old fake backends. Check their first example in their documentation here to learn how to use the new GenericBackend they have.

Since a lot has changed in Qiskit and PennyLane in two years (when the QuFI project was written), it’s possible that you will encounter many other similar errors. If you get more of these errors you should try looking up online to see what the new Qiskit functionality is in those cases.

I hope this helps you!

I switched over to the Brisbane backend.
Now I get a pennylane error from injector.py.
What happened to the qml.qfunc_transform decorator?
There is no pennylane page on that also.


    from qufi import execute_over_range, BernsteinVazirani, get_qiskit_coupling_map, read_results_directory, generate_all_statistics
  File "/media/xxx/C-UAS-DB1/QuFI/qufi/__init__.py", line 1, in <module>
    from qufi.injector import *
  File "/media/xxx/C-UAS-DB1/QuFI/qufi/injector.py", line 131, in <module>
    @qml.qfunc_transform
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages/pennylane/__init__.py", line 164, in __getattr__
    raise AttributeError(f"module 'pennylane' has no attribute '{name}'")
AttributeError: module 'pennylane' has no attribute 'qfunc_transform'

Replacing @qml.func_transform by @qml.transform solved the issue.

I was able to use the FakeSantiago backend by using the line:
from qiskit_ibm_runtime.fake_provider import FakeSantiago

Now I am getting a “cannot pickle ‘pennylane_lightning.lightning_qubit_ops.StateVectorC128’ object”
error issued by deepcopy() in injector.py. Any suggestions?

--------------------------------------------------------------------------------

Circuit Bernstein-Vazirani_4 start: 2024-05-08 13:50:21.185230
--------------------------------------------------------------------------------
Injecting circuit: Bernstein-Vazirani_4 theta0: 0 phi0: 0
Traceback (most recent call last):
  File "/media/xxx/C-UAS-DB1/QuFI/run_circuits.py", line 24, in <module>
    results_names = execute_over_range(circuits, angles, coupling_map=coupling_map, results_folder="./tmp/")
  File "/media/xxx/C-UAS-DB1/QuFI/qufi/injector.py", line 277, in execute_over_range
    copy_of_circuit = deepcopy(target_circuit)   # pickle error here
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: cannot pickle 'pennylane_lightning.lightning_qubit_ops.StateVectorC128' object

Hi @art,

Indeed @qml.func_transform was deprecated and you should now use @qml.transform. You can see more details in the Deprecations section of the documentation.

Ah it’s interesting to see that Qiskit has moved the fake providers to qiskit_ibm_runtime. Good find.

From your last error it seems that the QuFI project is using Python’s deepcopy to do something. this is being called in line 271 of the injector.py file and in other places too. It seems that this operation is incompatible with lightning.qubit. It looks like lightning.qubit is being called in QuFI’s circuit_generator and injector files so I would recommend that you change them to use default.qubit instead and test if this resolves the problem.

@CatalinaAlbornoz earlier I had made the lightning.qubit to default.qubit changes in injector.py but I also needed to make the same changes in circuit_generator.py. That fixed the deepcopy error.

How would I go about changing qml.qfunc_transform decorators to qml.transform for the following code (using @partial(…))?

@qml.qfunc_transform
def pl_insert_gate(tape, index, wire, theta=0, phi=0, lam=0):
    """Decorator qfunc_transform which inserts a single fault gate"""
    i = 0
    for gate in tape.operations + tape.measurements:
        # Ignore barriers and measurement gates
        if i == index:
            # If gate are not using a single qubit, insert one gate after each qubit
            qml.apply(gate)
            qml.U3(theta=theta, phi=phi, delta=lam, wires=wire, id="FAULT")
        else:
            qml.apply(gate)
        i = i + 1

def pl_generate_circuits(base_circuit, name, theta=0, phi=0, lam=0):
    """Generate all possible fault circuits"""
    mycircuits = []
    inj_info = []
    index_info = []
    op_info = []
    # with tape as tape:
    index = 0
    for op in base_circuit.tape.operations:
        for wire in op.wires:
            shots = 1024
            transformed_circuit = pl_insert_gate(index, wire, theta, phi, lam)(base_circuit.func)
            device = qml.device('default.qubit', wires=len(base_circuit.tape.wires), shots=shots)
            transformed_qnode = qml.QNode(transformed_circuit, device)
            log(f'Generated single fault circuit: {name} with fault on ({op.name}, wire:{wire}), theta = {theta}, phi = {phi}')
            #print(qml.draw(transformed_qnode)())
            transformed_qnode()
            mycircuits.append(transformed_qnode)
            inj_info.append(wire)
            op_info.append(op.name)
            index_info.append(index)
        index = index + 1
    log(f"{len(mycircuits)} circuits generated\n")
    return mycircuits, op_info, inj_info, index_info

Also note the @partial() decorator at the following page does not work:

I had to modify the code as follows:


import pennylane as qml
from functools import partial

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

#@partial(qml.transforms.insert, qml.AmplitudeDamping, 0.2, position="end")
#@qml.qnode(dev)
def f(w, x, y, z):
    qml.RX(w, wires=0)
    qml.RY(x, wires=1)
    qml.CNOT(wires=[0, 1])
    qml.RY(y, wires=0)
    qml.RX(z, wires=1)
    return qml.expval(qml.Z(0) @ qml.Z(1))

dev_noisy = qml.transforms.insert(dev, qml.AmplitudeDamping, 0.2, position="end")
qnode_noisy = qml.QNode(f, dev_noisy)
print(qnode_noisy(0.9, 0.4, 0.5, 0.6))
qml.about()

Output:

0.754846996885476
Name: PennyLane
Version: 0.36.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: https://github.com/PennyLaneAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-qiskit, PennyLane_Lightning

Platform info:           Linux-5.4.0-150-generic-x86_64-with-glibc2.27
Python version:          3.9.19
Numpy version:           1.23.5
Scipy version:           1.10.0
Installed devices:
- default.clifford (PennyLane-0.36.0)
- default.gaussian (PennyLane-0.36.0)
- default.mixed (PennyLane-0.36.0)
- default.qubit (PennyLane-0.36.0)
- default.qubit.autograd (PennyLane-0.36.0)
- default.qubit.jax (PennyLane-0.36.0)
- default.qubit.legacy (PennyLane-0.36.0)
- default.qubit.tf (PennyLane-0.36.0)
- default.qubit.torch (PennyLane-0.36.0)
- default.qutrit (PennyLane-0.36.0)
- default.qutrit.mixed (PennyLane-0.36.0)
- null.qubit (PennyLane-0.36.0)
- lightning.qubit (PennyLane-Lightning-0.36.0)
- qiskit.aer (PennyLane-qiskit-0.36.0)
- qiskit.basicaer (PennyLane-qiskit-0.36.0)
- qiskit.basicsim (PennyLane-qiskit-0.36.0)
- qiskit.ibmq (PennyLane-qiskit-0.36.0)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.36.0)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.36.0)
- qiskit.remote (PennyLane-qiskit-0.36.0)

Hi @art,

I’m glad to see that you fixed the deepcopy error!

I can confirm that the example here isn’t working. Thank you for reporting it! I’ll let you know about the teams’ response to this next week.

I’m glad that you managed to modify the code to make it work. Let me know if you have any further questions and thank you again for reporting the error in the example!

@CatalinaAlbornoz how would I convert the qml.qfunc_transform decorator to qml.transform for the pl_insert_gate() function (in injector.py)?

Hi @art, my colleague David has opened this Pull Request to fix the examples you mentioned in the documentation.

I don’t know exactly what the pl_insert_gate() function in injector.py is doing but below is the working example which adds a single-qubit amplitude damping error channel to the circuit (so it becomes a noisy circuit).

import pennylane as qml
from functools import partial

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

@partial(qml.transforms.insert, op=qml.AmplitudeDamping, op_args=0.2, position="end")
@qml.qnode(dev)
def f(w, x, y, z):
  qml.RX(w, wires=0)
  qml.RY(x, wires=1)
  qml.CNOT(wires=[0, 1])
  qml.RY(y, wires=0)
  qml.RX(z, wires=1)
  return qml.expval(qml.Z(0) @ qml.Z(1))

f(0.9, 0.4, 0.5, 0.6)

@CatalinaAlbornoz can you make the qml.qfunc_transform to qml.transform change for the code snippet in the “Transforms with parameters” section of the following page:

The code I wrote:

import pennylane as qml
from pennylane.tape import QuantumTape
from typing import Sequence, Callable

@qml.transform
def overrotate_rx(tape: QuantumTape, overrot_angle=0) -> (Sequence[QuantumTape], Callable):
    for op in tape.operation + tape.measurements:
        if op.name == "RX":
            qml.RX(op.parameters[0] + overrot_angle, wires=op.wires)
        else:
            qml.apply(op)

def circuit(x):
    qml.RX(x, wires=0)
    qml.CNOT(wires=[0, 1])
    qml.CNOT(wires=[1, 2])
    qml.Hadamard(wires=2)
    return qml.expval(qml.PauliZ(0))


dev = qml.device('default.qubit', wires=3)
transformed_circuit = overrotate_rx(0.1)(circuit)
qnode = qml.QNode(transformed_circuit, dev)
qnode(0.3)
print(qml.draw(qnode)(0.3))

gives the following error:


transformed_circuit = overrotate_rx(0.1)(circuit)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages/pennylane/transforms/core/transform_dispatcher.py", line 137, in __call__
    raise TransformError(
pennylane.transforms.core.transform_dispatcher.TransformError: Decorating a QNode with @transform_fn(**transform_kwargs) has been removed. Please decorate with @functools.partial(transform_fn, **transform_kwargs) instead, or call the transform directly using qnode = transform_fn(qnode, **transform_kwargs). Visit the deprecations page for more details: https://docs.pennylane.ai/en/stable/development/deprecations.html#completed-deprecation-cycles

Hi @art,

The blog is very old so it no longer contains the most recent way to use transforms. Below you can find a working example.

import pennylane as qml
from typing import Sequence, Callable
from pennylane.tape import QuantumTape

def overrotate_rx(tape: QuantumTape, overrot_angle=0) -> (Sequence[QuantumTape], Callable):

    operations = []
    for op in tape.operations:
        if op.name == "RX":
          operations.append(qml.RX(op.parameters[0]+overrot_angle, wires=op.wires))
        else:
          operations.append(op)

    new_tape = type(tape)(operations, tape.measurements, shots=tape.shots)

    def null_postprocessing(results):
        return results[0]
    
    return [new_tape], null_postprocessing

dev = qml.device("default.qubit")

@qml.qnode(device=dev)
def circuit(x):
    qml.RX(x, wires=0)
    qml.CNOT(wires=[0, 1])
    qml.CNOT(wires=[1, 2])
    qml.Hadamard(wires=2)
    return qml.expval(qml.PauliZ(0))

dispatched_transform = qml.transform(overrotate_rx)

transformed_qnode = dispatched_transform(circuit, overrot_angle=0.3)
qml.draw_mpl(circuit,decimals=1)(0.1)
qml.draw_mpl(transformed_qnode,decimals=1)(0.1)

I hope this helps!

@CatalinaAlbornoz I have gotten past the transform errors in qufi/injector.py by following your example code. I am now getting a “DefaultQubit has no attribute ‘num_wires’” error from pennylane’s device_api.py as follows (line numbers would have changed if you are referring to the legacy qufi code):


Running circuits
Traceback (most recent call last):
  File "/media/xxx/C-UAS-DB1/QuFI/run_circuits.py", line 24, in <module>
    results_names = execute_over_range(circuits, angles, coupling_map=coupling_map, results_folder="./tmp/")
  File "/media/xxx/C-UAS-DB1/QuFI/qufi/injector.py", line 328, in execute_over_range
    pl_inject(s, noise=noise)
  File "/media/xxx/C-UAS-DB1/QuFI/qufi/injector.py", line 277, in pl_inject
    circuitStruct.update(run_circuits( circuitStruct['base_circuit'], circuitStruct['generated_circuits'], noise=noise))
  File "/media/xxx/C-UAS-DB1/QuFI/qufi/injector.py", line 79, in run_circuits
    gold_device = qml.device('default.qubit', wires=base_circuit.device.num_wires)
  File "/home/xxx/anaconda/envs/qufi2/lib/python3.9/site-packages/pennylane/devices/device_api.py", line 181, in __getattr__
    raise AttributeError(
AttributeError: DefaultQubit has no attribute 'num_wires'. You may be looking for a property or method present in the legacy device interface. Please consult the DefaultQubit documentation for an updated list of public properties and methods.

What should be done in this case? I came across a similar error posting:

Hi @art ,

If you follow what the error message says you’ll notice that DefaultQubit no longer has a ‘num_wires’ attribute. You can instead try using the wires attribute, but please use it carefully since it’s a different attribute so you will need to debug on your own to ensure compatibility with your code.

num_wires indicates length of an array of wires
so base_circuit.device.num_wires should be
replaced by len(base_circuit.device.wires).
Code runs with that change.

It’s great to see that you could solve it @art !