How can I save the quantum circuit into disk and load from disk in PennyLane

Hi, I am trying to save the quantum circuit constructed by PennyLane into a file and back again. Is it supported by PennyLane now?

Looking forward to your suggestions.
Thanks.

Hi @Yang, it’s good to see you in the Forum!

You could use to_openqasm and from_qasm to do what you need.

import pennylane as qml

dev = qml.device("lightning.qubit",wires=1)

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

circuit.construct([0.5], {})
# Convert to QASM (str)
t = circuit.qtape.to_openqasm()
print(t)

# Remove the measurement
t_cut = t[:-23]
print(t_cut) 

This gives you a string that you can send to someone. The other person can then use the following code:

my_circuit = qml.from_qasm(t_cut) # Create a template

@qml.qnode(dev)
def new_circuit(y):
    # You can add new things to the circuit
    qml.RY(y, wires=0)
    # Add your old circuit
    my_circuit(wires=[0])
    return qml.expval(qml.PauliZ(0))

#Draw
drawer = qml.draw(new_circuit)
print(drawer(y = 0.3))

Does this work for what you need?

2 Likes

Yes, it is exactly what I need. Thanks very much.

Awesome! I’m glad this works for you.

Just to note, it appears that in Pennylane 0.33.1, this method changes the circuit by decomposing the constituent gates. For example, a Hadamard gate in the qasm is decomposed into a series of Ry, Rz gates in Pennylane.

After testing, I determined that this is due to the qml.from_qasm function, which reads in a Hadamard as a parametrised U gate. This is then decomposed if you extract the QASM.

I got around this by defining a custom parser which uses Python’s exec function to read in the QASM and constructs a Pennylane function from it. Obviously this is far from best practice, but it is a temporary fix.

I think this is a serious oversight which should be fixed: the Pennylane QASM parser should be able to convert all standard QASM gates into the corresponding gates in Pennylane, without defaulting to representing them as parametrised U gates.

Hey @babel! Welcome to the forum :slight_smile:

Can you share some code that demonstrates the behaviour you’re seeing? I tried this and it seems to behave nicely :thinking:

import pennylane as qml
​
with qml.tape.QuantumTape() as tape:
    qml.Hadamard(0)
​
qasm_repr = tape.to_openqasm()
print(qasm_repr)
​
with qml.tape.QuantumTape() as tape:
    qml.from_qasm(qasm_repr)()
​
print(tape.draw())
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
creg c[1];
h q[0];
measure q[0] -> c[0];

0: ──H─┤