Error measuring expval on qiskit cpu

Hello everyone! I was trying to use the qiskit plugin to get access to IBM QPUs, but I get the following error when measuring the expectation value of an operator: ValueError: The number of qubits of the circuit (127) does not match the number of qubits of the (0,)-th observable (4). According to this post the error is caused by the observable not being expressed using the Instruction Set Architecture of the QPU. How can I perform this optimisation in Pennylane, if this is the issue?

import pennylane as qml
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.least_busy(min_num_qubits=4)
print(backend.name)
device = qml.device("qiskit.remote", wires=4, backend=backend)

@qml.qnode(device)
def circuit_probs():
    qml.Hadamard(wires=0)
    return qml.probs()

@qml.qnode(device)
def circuit_expval():
    qml.Hadamard(wires=0)
    return qml.expval(qml.PauliZ(0))

print(circuit_probs())
print(circuit_expval())

If you want help with diagnosing an error, please put the full error message below:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent caall last)
Cell In[1], line 19
     16     return qml.expval(qml.PauliZ(0))
     18 print(circuit_probs())
---> 19 print(circuit_expval())

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/qnode.py:1020, in QNode.__caall__(self, *args, **kwargs)
   1018 if qml.capture.enabled():
   1019     return qml.capture.qnode_caall(self, *args, **kwargs)
-> 1020 return self._impl_caall(*args, **kwargs)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/qnode.py:1008, in QNode._impl_caall(self, *args, **kwargs)
   1005 self._update_gradient_fn(shots=override_shots, tape=self._tape)
   1007 try:
-> 1008     res = self._execution_component(args, kwargs, override_shots=override_shots)
   1009 finally:
   1010     if old_interface == "auto":

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/qnode.py:957, in QNode._execution_component(self, args, kwargs, override_shots)
    951     warnings.filterwarnings(
    952         action="ignore",
    953         message=r".*argument is deprecated and will be removed in version 0.39.*",
    954         category=qml.PennyLaneDeprecationWarning,
    955     )
    956     # pylint: disable=unexpected-keyword-arg
--> 957     res = qml.execute(
    958         (self._tape,),
    959         device=self.device,
    960         gradient_fn=self.gradient_fn,
    961         interface=self.interface,
    962         transform_program=full_transform_program,
    963         inner_transform=inner_transform_program,
    964         config=config,
    965         gradient_kwargs=self.gradient_kwargs,
    966         override_shots=override_shots,
    967         **execute_kwargs,
    968     )
    969 res = res[0]
    971 # convert result to the interface in case the qfunc has no parameters

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/execution.py:771, in execute(tapes, device, gradient_fn, interface, transform_program, inner_transform, config, grad_on_execution, gradient_kwargs, cache, cachesize, max_diff, override_shots, expand_fn, max_expansion, device_batch_transform, device_vjp, mcm_config)
    763 ml_boundary_execute = _get_ml_boundary_execute(
    764     interface,
    765     config.grad_on_execution,
    766     config.use_device_jacobian_product,
    767     differentiable=max_diff > 1,
    768 )
    770 if interface in jpc_interfaces:
--> 771     results = ml_boundary_execute(tapes, execute_fn, jpc, device=device)
    772 else:
    773     results = ml_boundary_execute(
    774         tapes, device, execute_fn, gradient_fn, gradient_kwargs, _n=1, max_diff=max_diff
    775     )

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/interfaces/autograd.py:147, in autograd_execute(tapes, execute_fn, jpc, device)
    142 # pylint misidentifies autograd.builtins as a dict
    143 # pylint: disable=no-member
    144 parameters = autograd.builtins.tuple(
    145     [autograd.builtins.list(t.get_parameters()) for t in tapes]
    146 )
--> 147 return _execute(parameters, tuple(tapes), execute_fn, jpc)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/autograd/tracer.py:48, in primitive.<locals>.f_wrapped(*args, **kwargs)
     46     return new_box(ans, trace, node)
     47 else:
---> 48     return f_raw(*args, **kwargs)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/interfaces/autograd.py:168, in _execute(parameters, tapes, execute_fn, jpc)
    150 @autograd.extend.primitive
    151 def _execute(
    152     parameters,
   (...)
    155     jpc,
    156 ):  # pylint: disable=unused-argument
    157     """Autodifferentiable wrapper around a way of executing tapes.
    158 
    159     Args:
   (...)
    166 
    167     """
--> 168     return execute_fn(tapes)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/workflow/execution.py:212, in _make_inner_execute.<locals>.inner_execute(tapes, **_)
    209 transformed_tapes, transform_post_processing = transform_program(tapes)
    211 if transformed_tapes:
--> 212     results = device.execute(transformed_tapes, execution_config=execution_config)
    213 else:
    214     results = ()

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane_qiskit/qiskit_device.py:66, in custom_simulator_tracking.<locals>.execute(self, circuits, execution_config)
     64 @wraps(tracked_execute)
     65 def execute(self, circuits, execution_config=DefaultExecutionConfig):
---> 66     results = tracked_execute(self, circuits, execution_config)
     67     if self.tracker.active:
     68         res = []

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane/devices/modifiers/simulator_tracking.py:30, in _track_execute.<locals>.execute(self, circuits, execution_config)
     28 @wraps(untracked_execute)
     29 def execute(self, circuits, execution_config=DefaultExecutionConfig):
---> 30     results = untracked_execute(self, circuits, execution_config)
     31     if isinstance(circuits, QuantumScript):
     32         batch = (circuits,)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane_qiskit/qiskit_device.py:590, in QiskitDevice.execute(self, circuits, execution_config)
    587     finally:
    588         session.close()
--> 590 with execute_circuits(session) as results:
    591     return results

File ~/miniforge3/envs/stations/lib/python3.10/contextlib.py:135, in _GeneratorContextManager.__enter__(self)
    133 del self.args, self.kwds, self.func
    134 try:
--> 135     return next(self.gen)
    136 except StopIteration:
    137     raise RuntimeError("generator didn't yield") from None

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane_qiskit/qiskit_device.py:585, in QiskitDevice.execute.<locals>.execute_circuits(session)
    583         else:
    584             execute_fn = self._execute_sampler
--> 585         results.append(execute_fn(circ, session))
    586     yield results
    587 finally:

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/pennylane_qiskit/qiskit_device.py:656, in QiskitDevice._execute_estimator(self, circuit, session)
    651 # split into one caall per measurement
    652 # could technically be more efficient if there are some observables where we ask
    653 # for expectation value and variance on the same observable, but spending time on
    654 # that right now feels excessive
    655 circ_and_obs = [(compiled_circuits[0], pauli_observables)]
--> 656 result = estimator.run(
    657     circ_and_obs,
    658     precision=np.sqrt(1 / circuit.shots.total_shots) if circuit.shots else None,
    659 ).result()
    660 self._current_job = result
    661 result = self._process_estimator_job(circuit.measurements, result)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/qiskit_ibm_runtime/estimator.py:191, in EstimatorV2.run(self, pubs, precision)
    189     if precision <= 0:
    190         raise ValueError("The precision value must be strictly greater than 0.")
--> 191 coerced_pubs = [EstimatorPub.coerce(pub, precision) for pub in pubs]
    192 validate_estimator_pubs(coerced_pubs)
    193 return self._run(coerced_pubs)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/qiskit_ibm_runtime/estimator.py:191, in <listcomp>(.0)
    189     if precision <= 0:
    190         raise ValueError("The precision value must be strictly greater than 0.")
--> 191 coerced_pubs = [EstimatorPub.coerce(pub, precision) for pub in pubs]
    192 validate_estimator_pubs(coerced_pubs)
    193 return self._run(coerced_pubs)

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/qiskit/primitives/containers/estimator_pub.py:162, in EstimatorPub.coerce(cls, pub, precision)
    159 if len(pub) > 3 and pub[3] is not None:
    160     precision = pub[3]
--> 162 return cls(
    163     circuit=circuit,
    164     observables=observables,
    165     parameter_values=parameter_values,
    166     precision=precision,
    167     validate=True,
    168 )

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/qiskit/primitives/containers/estimator_pub.py:85, in EstimatorPub.__init__(self, circuit, observables, parameter_values, precision, validate)
     79     raise ValueError(
     80         f"The observables shape {self.observables.shape} and the "
     81         f"parameter values shape {self.parameter_values.shape} are not broadcastable."
     82     ) from ex
     84 if validate:
---> 85     self.validate()

File ~/miniforge3/envs/stations/lib/python3.10/site-packages/qiskit/primitives/containers/estimator_pub.py:188, in EstimatorPub.validate(self)
    186     num_qubits = len(next(iter(observable)))
    187     if self.circuit.num_qubits != num_qubits:
--> 188         raise ValueError(
    189             f"The number of qubits of the circuit ({self.circuit.num_qubits}) does "
    190             f"not match the number of qubits of the {i}-th observable ({num_qubits})."
    191         )
    193 # Cross validate circuits and parameter_values
    194 num_parameters = self.parameter_values.num_parameters

ValueError: The number of qubits of the circuit (127) does not match the number of qubits of the (0,)-th observable (4).

And, finally, make sure to include the versions of your packages. Specifically, show us the output of qml.about().

Name: PennyLane
Version: 0.38.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: /Users/manu/miniforge3/envs/stations/lib/python3.10/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, packaging, pennylane-lightning, requests, rustworkx, scipy, toml, typing-extensions
Required-by: PennyLane-qiskit, PennyLane_Lightning

Platform info:           macOS-14.7-x86_64-i386-64bit
Python version:          3.10.13
Numpy version:           1.26.4
Scipy version:           1.12.0
Installed devices:
- qiskit.aer (PennyLane-qiskit-0.38.0)
- qiskit.basicaer (PennyLane-qiskit-0.38.0)
- qiskit.basicsim (PennyLane-qiskit-0.38.0)
- qiskit.remote (PennyLane-qiskit-0.38.0)
- lightning.qubit (PennyLane_Lightning-0.38.0)
- default.clifford (PennyLane-0.38.0)
- default.gaussian (PennyLane-0.38.0)
- default.mixed (PennyLane-0.38.0)
- default.qubit (PennyLane-0.38.0)
- default.qubit.autograd (PennyLane-0.38.0)
- default.qubit.jax (PennyLane-0.38.0)
- default.qubit.legacy (PennyLane-0.38.0)
- default.qubit.tf (PennyLane-0.38.0)
- default.qubit.torch (PennyLane-0.38.0)
- default.qutrit (PennyLane-0.38.0)
- default.qutrit.mixed (PennyLane-0.38.0)
- default.tensor (PennyLane-0.38.0)
- null.qubit (PennyLane-0.38.0)

Hi @ecasciaro_unifi , welcome to the Forum! You should specify wires=127 since this is how many qubits the actual device has.

Let me know if this fixes the issue for you!

1 Like