[BUG] `qml.draw` fails for templates without a custom `adjoint` method (`expansion_strategy=None`)
See original GitHub issueExpected behavior
dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def qpe_circuit():
qml.adjoint(qml.QuantumPhaseEstimation)(
qml.PauliX.matrix,
target_wires=[0],
estimation_wires=[1],
)
return qml.state()
print(qml.draw(qpe_circuit)())
Executes correctly.
Actual behavior
An error is raised:
~/xanadu/pennylane/pennylane/circuit_drawer/representation_resolver.py in element_representation(self, element, wire)
487 return self.output_representation(element, wire)
488
--> 489 return self.operator_representation(element, wire)
~/xanadu/pennylane/pennylane/circuit_drawer/representation_resolver.py in operator_representation(self, op, wire)
420 elif len(qml.math.shape(op.data[0])) != 0:
421 print(name)
--> 422 representation = name + RepresentationResolver._format_matrix_arguments(
423 op.data, "M", self.matrix_cache
424 )
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Additional information
The issue seems to arise with any template that doesn’t define the adjoint method. The specific line in the traceback errors out because a QuantumTape object is being processed and it doesn’t have a name attribute defined.
When expansion_strategy=device is set, drawing concludes successfully and draws the circuit as expected.
Source code
No response
Tracebacks
No response
System information
Name: PennyLane
Version: 0.20.0.dev0
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/antal/xanadu/pennylane
Requires: numpy, scipy, networkx, autograd, toml, appdirs, semantic_version, autoray, cachetools, pennylane-lightning
Required-by: PennyLane-Cirq, PennyLane-Orquestra, PennyLane-SF, pennylane-qulacs, PennyLane-IonQ, amazon-braket-pennylane-plugin, PennyLane-Honeywell, PennyLane-qiskit, PennyLane-AQT, PennyLane-Qchem, PennyLane-PQ, PennyLane-Forest, PennyLane-Lightning, PennyLane-qsharp
Platform info: Linux-5.11.0-40-generic-x86_64-with-glibc2.10
Python version: 3.8.5
Numpy version: 1.21.4
Scipy version: 1.7.3
Installed devices:
- cirq.mixedsimulator (PennyLane-Cirq-0.17.1)
- cirq.pasqal (PennyLane-Cirq-0.17.1)
- cirq.qsim (PennyLane-Cirq-0.17.1)
- cirq.qsimh (PennyLane-Cirq-0.17.1)
- cirq.simulator (PennyLane-Cirq-0.17.1)
- orquestra.forest (PennyLane-Orquestra-0.15.0)
- orquestra.ibmq (PennyLane-Orquestra-0.15.0)
- orquestra.qiskit (PennyLane-Orquestra-0.15.0)
- orquestra.qulacs (PennyLane-Orquestra-0.15.0)
- strawberryfields.fock (PennyLane-SF-0.16.0.dev0)
- strawberryfields.gaussian (PennyLane-SF-0.16.0.dev0)
- strawberryfields.gbs (PennyLane-SF-0.16.0.dev0)
- strawberryfields.remote (PennyLane-SF-0.16.0.dev0)
- strawberryfields.tf (PennyLane-SF-0.16.0.dev0)
- qulacs.simulator (pennylane-qulacs-0.17.0.dev0)
- ionq.qpu (PennyLane-IonQ-0.17.0.dev0)
- ionq.simulator (PennyLane-IonQ-0.17.0.dev0)
- braket.aws.qubit (amazon-braket-pennylane-plugin-1.4.1.dev0)
- braket.local.qubit (amazon-braket-pennylane-plugin-1.4.1.dev0)
- honeywell.hqs (PennyLane-Honeywell-0.16.0.dev0)
- qiskit.aer (PennyLane-qiskit-0.18.0.dev0)
- qiskit.basicaer (PennyLane-qiskit-0.18.0.dev0)
- qiskit.ibmq (PennyLane-qiskit-0.18.0.dev0)
- aqt.noisy_sim (PennyLane-AQT-0.18.0)
- aqt.sim (PennyLane-AQT-0.18.0)
- projectq.classical (PennyLane-PQ-0.18.0.dev0)
- projectq.ibm (PennyLane-PQ-0.18.0.dev0)
- projectq.simulator (PennyLane-PQ-0.18.0.dev0)
- forest.numpy_wavefunction (PennyLane-Forest-0.18.0.dev0)
- forest.qvm (PennyLane-Forest-0.18.0.dev0)
- forest.wavefunction (PennyLane-Forest-0.18.0.dev0)
- lightning.qubit (PennyLane-Lightning-0.19.0.dev0)
- microsoft.QuantumSimulator (PennyLane-qsharp-0.19.0)
- default.gaussian (PennyLane-0.20.0.dev0)
- default.mixed (PennyLane-0.20.0.dev0)
- default.qubit (PennyLane-0.20.0.dev0)
- default.qubit.autograd (PennyLane-0.20.0.dev0)
- default.qubit.jax (PennyLane-0.20.0.dev0)
- default.qubit.tf (PennyLane-0.20.0.dev0)
- default.qubit.torch (PennyLane-0.20.0.dev0)
- default.tensor (PennyLane-0.20.0.dev0)
- default.tensor.tf (PennyLane-0.20.0.dev0)
###
- [X] I have searched exisisting GitHub issues to make sure the issue does not already exist.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (5 by maintainers)
Top Results From Across the Web
No results found
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

The problem is that the information about the template is lost. Since the adjoint method is not defined for
QuantumPhaseEstimation, the template is expanded into a tape and the adjoint is computed on the tape. All the drawer then sees is a tape with operations inside. So while in this instance the tape came from an adjointed template, it could just as well come from the manual placement of a tape in the operations list:Note that the desired behaviour you describe does happen when a template defines the adjoint method via
.inv(), for example the QFT template:prints as:
So I think in addition to supporting tapes in the drawer, a fix to this bug could include defining the adjoint method for the QuantumPhaseEstimation template so that its adjoint is properly drawn.
#1973 removed the issue for the QuantumPhaseEstimation template.