softwareQinc / staq

Full-stack quantum processing toolkit
https://iopscience.iop.org/article/10.1088/2058-9565/ab9359/pdf
MIT License
154 stars 28 forks source link

JSON parse issue for device mapping #66

Closed manavbabel closed 11 months ago

manavbabel commented 11 months ago

I'm trying to transpile a circuit to a custom device using pystaq.map, but I'm getting a JSON parse error which seems to be a bug with the module.

I'm using pystaq version 3.3 on Windows 10 with Python 3.11.

Here's a minimum working example:

import pystaq
import json

# qubit graph is a ring of four qubits
connectivity = [[0, 1], [1, 2], [2, 3], [3, 0]]

# define a QASM circuit
circ = """
OPENQASM 2.0;
include "qelib1.inc";

// Qubits: [q_0, q_1]
qreg q[2];

cx q[1],q[0];
t q[1];
cx q[0],q[1];
t q[0];"""

# convert to a pystaq circuit
p = pystaq.parse_str(circ)

# create a pystaq Device with four qubits
device = pystaq.Device(4)
[device.add_edge(*i) for i in connectivity]

# create json representation of the device
# and pass it to the pystaq map function
device_json = json.dumps(json.loads(str(device)))
print(device_json)
pystaq.map(p, device_json=device_json)

And the output is

{"couplings": [{"control": 0, "target": 1}, {"control": 0, "target": 3}, {"control": 1, "target": 0}, {"control": 1, "target": 2}, {"control": 2, "target": 1}, {"control": 2, "target": 3}, {"control": 3, "target": 0}, {"control": 3, "target": 2}], "name": "Custom Device", "qubits": [{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}]}

RuntimeError                              Traceback (most recent call last)
Untitled-1.ipynb Cell 1 line 3
     [27](vscode-notebook-cell:Untitled-1.ipynb?jupyter-notebook#W0sdW50aXRsZWQ%3D?line=26) # create json representation of the device
     [28](vscode-notebook-cell:Untitled-1.ipynb?jupyter-notebook#W0sdW50aXRsZWQ%3D?line=27) # and pass it to the pystaq map function
     [29](vscode-notebook-cell:Untitled-1.ipynb?jupyter-notebook#W0sdW50aXRsZWQ%3D?line=28) device_json = json.dumps(json.loads(str(device)))
---> [30](vscode-notebook-cell:Untitled-1.ipynb?jupyter-notebook#W0sdW50aXRsZWQ%3D?line=29) pystaq.map(p, device_json=device_json)

RuntimeError: [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal

However, I know that the JSON created is valid as I'm using the default Python module for it, so I think this is a bug in the implementation of map.

vsoftco commented 11 months ago

thanks, we'll take a look

vsoftco commented 11 months ago

@manavbabel In the current API, the device_json argument should be the name of the file where the .json spec of the connectivity is written to. If empty, then it'll assume by default full connectivity. So you'd need to dump the json to a file, e.g. connectivity.json, then pass "connectivity.json" as the argument, i.e., device_json="connectivity.json". Full example below:

import pystaq

# qubit graph is a ring of four qubits
connectivity = [[0, 1], [1, 2], [2, 3], [3, 0]]

# define a QASM circuit
circ = """
OPENQASM 2.0;
include "qelib1.inc";

// Qubits: [q_0, q_1]
qreg q[2];

cx q[1],q[0];
t q[1];
cx q[0],q[1];
t q[0];"""

# convert to a pystaq circuit
p = pystaq.parse_str(circ)

# create a pystaq Device with four qubits
device = pystaq.Device(4)
[device.add_edge(*i) for i in connectivity]

# this doesn't work
# device_json = json.dumps(json.loads(str(device)))

with open("device.json", "w") as file:
    file.write(str(device))
print(device)

pystaq.map(p, device_json="device.json")
print(p)
manavbabel commented 11 months ago

@vsoftco Thanks for the help, that fixes it. The documentation for map is:

Help on built-in function map in module pystaq:

map(...) method of builtins.PyCapsule instance
    map(prog: pystaq.Program, layout: str = 'linear', mapper: str = 'swap', evaluate_all: bool = False, device_json: str = '') -> None

    Map circuit to a physical device

Maybe it would be worth updating this to note that device_json must have a filename passed to it, as currently a json string is implied, and I couldn't find the filename requirement myself.

Thanks again!

vsoftco commented 11 months ago

@manavbabel Totally agree. The documentation is generated automatically from the C++ wrapper https://github.com/softwareQinc/staq/blob/main/pystaq/staq_wrapper.cpp (this is how we wrap the C++ code to Python). We'll update the documentation, or add an overload that takes a json string, as in your initial example. Keeping this issue open for now.

vsoftco commented 11 months ago

@manavbabel Fixed by the last commit, now the documentation is a bit more clear.