I've done a superficial search in each of the qiskit, cirq, and braket open source repositories for such a feature, but can't find any explicit examples of this functionality. I'm wondering if anyone knows more about how the quantum circuit objects are constructed behind the scenes in one or each of these packages and if any of the above-mentioned packages store circuit information in a data structure accessible to the user that could be translated to a JSON, or conversely, translate an appropriately formatted JSON to said data-structure and construct a circuit object through the "back door" in this way?
1 Answer
For Qiskit if your goal is to just export the circuit (or circuits) object to a file and then to create an identical circuit later I would suggest looking at QPY serialization: https://qiskit.org/documentation/apidoc/qpy.html it's not a JSON serialization format but a binary one. It's designed to be a lossless backwards compatible format for saving and loading Qiskit's QuantumCircuit
object. If you need it to be JSON you can base64 encode it to a string and embed it into a JSON payload with something like:
import io
import json
import base64
from qiskit.circuit import qpy_serialization
from qiskit.circuit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
buf = io.BytesIO()
qpy_serialization.dump(circuit, buf)
json_str = json.dumps({
'circuits': base64.b64encode(buf.getvalue()).decode('utf8')
})
which will set json_str
as a JSON payload like:
{"circuits": "B64 Encoded QPY"}
where "B64 Encoded QPY"
is a large unreadable string. But then you can load this with Qiskit using:
circuit_json = json.loads(json_str)
qpy_file = io.BytesIO(base64.b64decode(circuit_json["circuits"]))
circuit = qpy_serialization.load(qpy_file)[0] # qpy works with multiple circuits at a time and returns a list
If this isn't a viable solution for what you need, you can look at Qobj which is a JSON payload format defined here: https://arxiv.org/abs/1809.03452 that you can use with something like:
from qiskit import assemble
json_str = json.dumps(assemble(circuit).to_dict())
and loaded with:
from qiskit.assembler import disassemble
from qiskit.qobj import QasmQobj
qasm_dict = json.loads(json_str)
circuits, _, __ = disassemble(QasmQobj.from_dict(qasm_dict))
circuit = circuits[0]
The tradeoff with Qobj is that it's not designed to be a lossless representation of a QuantumCircuit
object and more a job submission payload for running on quantum computers. So it can't represent all the higher level objects a QuantumCircuit
may contain.
However, if your goal is interoperability between tools then I would suggest looking at the OpenQASM language. OpenQASM 2.0 [1][2] is pretty widely supported by most quantum computing software (including Qiskit and Cirq), and the next version of the language OpenQASM 3.0 [3][4] is starting to be used.
[1] https://arxiv.org/abs/1707.03429
[2] https://github.com/Qiskit/openqasm/tree/OpenQASM2.x
cirq.to_json
andcirq.read_json
methods: quantumai.google/cirq/interop. $\endgroup$