Hello.
I am currently trying to create a circuit that has both mid circuit measurements and noise. Below is a simple example of a circuit that has both features.
import pennylane as qml
from pennylane import numpy as np
num_qubits = 2
dev = qml.device('default.mixed', wires = num_qubits)
@qml.qnode(dev)
def circuit():
qml.Hadamard(wires = 0)
qml.CNOT(wires = [0,1])
qml.measure(0, reset = True)
qml.AmplitudeDamping(0.5, wires = 0)
qml.AmplitudeDamping(0.5, wires = 1)
return qml.expval(qml.PauliZ(0)@qml.PauliZ(1))
circuit()
Running this code gives the error message which you can find below. The error seems to be related to not finding some wires.
Here is the error message
---------------------------------------------------------------------------
WireError Traceback (most recent call last)
/usr/local/lib/python3.11/dist-packages/pennylane/devices/_legacy_device.py in map_wires(self, wires)
387 try:
--> 388 mapped_wires = wires.map(self.wire_map)
389 except WireError as e:
18 frames
/usr/local/lib/python3.11/dist-packages/pennylane/wires.py in map(self, wire_map)
324 if w not in wire_map:
--> 325 raise WireError(f"No mapping for wire label {w} specified in wire map {wire_map}.")
326
WireError: No mapping for wire label 2 specified in wire map OrderedDict([(0, 0), (1, 1)]).
The above exception was the direct cause of the following exception:
WireError Traceback (most recent call last)
<ipython-input-7-f80880ac011a> in <cell line: 0>()
11 return qml.expval(qml.PauliZ(0)@qml.PauliZ(1))
12
---> 13 circuit()
/usr/local/lib/python3.11/dist-packages/pennylane/workflow/qnode.py in __call__(self, *args, **kwargs)
903 if qml.capture.enabled():
904 return capture_qnode(self, *args, **kwargs)
--> 905 return self._impl_call(*args, **kwargs)
906
907
/usr/local/lib/python3.11/dist-packages/pennylane/workflow/qnode.py in _impl_call(self, *args, **kwargs)
879 self._transform_program.set_classical_component(self, args, kwargs)
880
--> 881 res = qml.execute(
882 (tape,),
883 device=self.device,
/usr/local/lib/python3.11/dist-packages/pennylane/workflow/execution.py in execute(tapes, device, diff_method, interface, transform_program, inner_transform, config, grad_on_execution, gradient_kwargs, cache, cachesize, max_diff, device_vjp, mcm_config, gradient_fn)
230 return post_processing(tapes)
231
--> 232 results = run(tapes, device, config, inner_transform)
233 return post_processing(results)
/usr/local/lib/python3.11/dist-packages/pennylane/workflow/run.py in run(tapes, device, config, inner_transform_program)
285 )
286 if no_interface_boundary_required:
--> 287 results = inner_execute(tapes)
288 return results
289
/usr/local/lib/python3.11/dist-packages/pennylane/workflow/run.py in inner_execute(tapes)
245
246 if transformed_tapes:
--> 247 results = device.execute(transformed_tapes, execution_config=execution_config)
248 else:
249 results = ()
/usr/local/lib/python3.11/dist-packages/pennylane/devices/modifiers/single_tape_support.py in execute(self, circuits, execution_config)
30 is_single_circuit = True
31 circuits = (circuits,)
---> 32 results = batch_execute(self, circuits, execution_config)
33 return results[0] if is_single_circuit else results
34
/usr/local/lib/python3.11/dist-packages/pennylane/devices/legacy_facade.py in execute(self, circuits, execution_config)
372 first_shot = circuits[0].shots
373 if all(t.shots == first_shot for t in circuits):
--> 374 return _set_shots(dev, first_shot)(dev.batch_execute)(circuits, **kwargs)
375 return tuple(
376 _set_shots(dev, t.shots)(dev.batch_execute)((t,), **kwargs)[0] for t in circuits
/usr/lib/python3.11/contextlib.py in inner(*args, **kwds)
79 def inner(*args, **kwds):
80 with self._recreate_cm():
---> 81 return func(*args, **kwds)
82 return inner
83
/usr/local/lib/python3.11/dist-packages/pennylane/devices/_qubit_device.py in batch_execute(self, circuits, **kwargs)
481 self.reset()
482
--> 483 res = self.execute(circuit, **kwargs)
484 results.append(res)
485
/usr/local/lib/python3.11/dist-packages/pennylane/logging/decorators.py in wrapper_entry(*args, **kwargs)
59 **_debug_log_kwargs,
60 )
---> 61 return func(*args, **kwargs)
62
63 @wraps(func)
/usr/local/lib/python3.11/dist-packages/pennylane/devices/default_mixed.py in execute(self, circuit, **kwargs)
851 wires_list.append(m.wires)
852 self.measured_wires = qml.wires.Wires.all_wires(wires_list)
--> 853 return super().execute(circuit, **kwargs)
854
855 @debug_logger
/usr/local/lib/python3.11/dist-packages/pennylane/devices/_qubit_device.py in execute(self, circuit, **kwargs)
269 return tuple(results)
270 # apply all circuit operations
--> 271 self.apply(
272 circuit.operations,
273 rotations=self._get_diagonalizing_gates(circuit),
/usr/local/lib/python3.11/dist-packages/pennylane/logging/decorators.py in wrapper_entry(*args, **kwargs)
59 **_debug_log_kwargs,
60 )
---> 61 return func(*args, **kwargs)
62
63 @wraps(func)
/usr/local/lib/python3.11/dist-packages/pennylane/devices/default_mixed.py in apply(self, operations, rotations, **kwargs)
866
867 for operation in operations:
--> 868 self._apply_operation(operation)
869
870 # store the pre-rotated state
/usr/local/lib/python3.11/dist-packages/pennylane/devices/default_mixed.py in _apply_operation(self, operation)
793 self._apply_channel_tensordot(matrices, wires)
794 else:
--> 795 self._apply_channel(matrices, wires)
796
797 # pylint: disable=arguments-differ
/usr/local/lib/python3.11/dist-packages/pennylane/devices/default_mixed.py in _apply_channel(self, kraus, wires)
413 wires (Wires): target wires
414 """
--> 415 channel_wires = self.map_wires(wires)
416 rho_dim = 2 * self.num_wires
417 num_ch_wires = len(channel_wires)
/usr/local/lib/python3.11/dist-packages/pennylane/devices/_legacy_device.py in map_wires(self, wires)
388 mapped_wires = wires.map(self.wire_map)
389 except WireError as e:
--> 390 raise WireError(
391 f"Did not find some of the wires {wires} on device with wires {self.wires}."
392 ) from e
WireError: Did not find some of the wires Wires([0, 2]) on device with wires Wires([0, 1]).
I have found that simply adding one qubit to the device solves the error message and the circuit seems to give the correct output.
Unfortunately this is really a bad solution for the code I am developing since I am applying many mid circuits measurements and the more mid circuits measurements the more extra qubits one needs to add, making everything unpracticable. As an example here is a circuit with 2 mid circuit measurements and you’ll find that 2 qubits need to be added for the error to go away.
import pennylane as qml
from pennylane import numpy as np
num_qubits = 2
dev = qml.device('default.mixed', wires = num_qubits)
@qml.qnode(dev)
def circuit():
qml.Hadamard(wires = 0)
qml.CNOT(wires = [0,1])
qml.measure(0, reset = True)
qml.AmplitudeDamping(0.5, wires = 0)
qml.AmplitudeDamping(0.5, wires = 1)
qml.RY(np.pi/2, wires = 0)
qml.measure(0, reset = True)
return qml.expval(qml.PauliZ(0)@qml.PauliZ(1))
circuit()
Do you have any recommendations on how to solve this issue without changing the number of qubits?
Here is information on the pennylane version.
Pennylane Version:
Name: PennyLane
Version: 0.40.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: /usr/local/lib/python3.11/dist-packages
Requires: appdirs, autograd, autoray, cachetools, diastatic-malt, networkx, numpy, packaging, pennylane-lightning, requests, rustworkx, scipy, tomlkit, typing-extensions
Required-by: PennyLane_Lightning
Platform info: Linux-6.1.85+-x86_64-with-glibc2.35
Python version: 3.11.11
Numpy version: 2.0.2
Scipy version: 1.14.1
Installed devices:
- default.clifford (PennyLane-0.40.0)
- default.gaussian (PennyLane-0.40.0)
- default.mixed (PennyLane-0.40.0)
- default.qubit (PennyLane-0.40.0)
- default.qutrit (PennyLane-0.40.0)
- default.qutrit.mixed (PennyLane-0.40.0)
- default.tensor (PennyLane-0.40.0)
- null.qubit (PennyLane-0.40.0)
- reference.qubit (PennyLane-0.40.0)
- lightning.qubit (PennyLane_Lightning-0.40.0)