Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding WASM support #77

Merged
merged 31 commits into from
Jan 23, 2024
Merged

Adding WASM support #77

merged 31 commits into from
Jan 23, 2024

Conversation

neal-erickson
Copy link
Contributor

Allowing WASM to work correctly from both the Circuit construction approach as well as allowing it to be passed in on the CLI for PECOS round-tripping.

.gitignore Outdated Show resolved Hide resolved
.pre-commit-config.yaml Outdated Show resolved Hide resolved
pytket/phir/phirgen.py Outdated Show resolved Hide resolved
tests/data/qasm/bell.qasm Outdated Show resolved Hide resolved
tests/test_api.py Outdated Show resolved Hide resolved
pytket/phir/phirgen.py Outdated Show resolved Hide resolved
pytket/phir/cli.py Show resolved Hide resolved
ruff.toml Outdated Show resolved Hide resolved
pytket/phir/cli.py Show resolved Hide resolved
@qartik qartik linked an issue Jan 4, 2024 that may be closed by this pull request
Copy link
Member

@qartik qartik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few more small suggestions, I still need to test the PR locally on my machine.

Edit: Done, looking good. Will wait for the test update before approval.

pytket/phir/cli.py Outdated Show resolved Hide resolved
pytket/phir/cli.py Outdated Show resolved Hide resolved
pytket/phir/phirgen.py Outdated Show resolved Hide resolved
@qciaran
Copy link
Collaborator

qciaran commented Jan 9, 2024

I primarily use pytket.phir.api.pytket_to_phir() or pytket.phir.api.qasm_to_phir(). It seems like these do not include wasm input. I see the CLI has the option to read in a wasm file. Also, when running wasm, I often directly supply the wasm byte object, so if possible it would be nice to either supply the byte object or file path.

@qciaran
Copy link
Collaborator

qciaran commented Jan 9, 2024

I get what I expect when running a simulation after generating PHIR from using circuit_from_qasm_wasm and pytket_to_phir.

tests/data/qasm/bell.qasm Outdated Show resolved Hide resolved
tests/test_api.py Outdated Show resolved Hide resolved
tests/test_api.py Outdated Show resolved Hide resolved
tests/test_api.py Outdated Show resolved Hide resolved
@qartik
Copy link
Member

qartik commented Jan 18, 2024

Looking good, thanks for finding a solution for consuming wat files. It will be nice if we can consume either wasm or wat files through the CLI as well. Could you also update the README after making changes to the CLI?

Copy link
Member

@qartik qartik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Member

@qartik qartik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noticed by @Asa-Kosto-QTM in #96, the tket opt level arg needs to be handled correctly here. Currently, showing up as a merge conflict.

@neal-erickson
Copy link
Contributor Author

@qartik tket_opt_level fix was already in place due to CLI changes. main merged into this branch.


wasm_bytes = get_wat_as_wasm_bytes(WatFile.add)

wasm_uid = hashlib.sha256(base64.b64encode(wasm_bytes)).hexdigest()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


phir = json.loads(phir_str)

expected_metadata = {"ff_object": (f"WASM module uid: {w!s}")}
Copy link
Member

@qartik qartik Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, since we are in pytket land, we can just use the string representation of the WasmFileHandler instance.

qartik
qartik previously approved these changes Jan 22, 2024
Copy link
Member

@qartik qartik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@qartik
Copy link
Member

qartik commented Jan 23, 2024

It will be nice if we can consume either wasm or wat files through the CLI as well.

I was trying to see if I can add the functionality to accept .wat files but noticed that currently even .wasm files fail with an error:

❯ cat wasm.qasm
OPENQASM 2.0;
include "qelib1.inc";

qreg q[2];
h q;
ZZ q[1],q[0];
creg cr[3];
creg cs[3];
creg co[3];
measure q[0]->cr[0];
measure q[1]->cr[1];

cs = cr;
co = add(cr, cs);

❯ phirc -v -w add.wasm wasm.qasm
Processing wasm.qasm
Including WASM from file add.wasm

PHIR to be simulated:
{"format": "PHIR/JSON", "version": "0.1.0", "metadata": {"source": "pytket-phir v0.2.2.dev35", "strict_parallelism": true}, "ops": [{"data": "qvar_define", "data_type": "qubits", "variable": "q", "size": 2}, {"data": "cvar_define", "data_type": "u32", "variable": "cr", "size": 3}, {"data": "cvar_define", "data_type": "u32", "variable": "cs", "size": 3}, {"data": "cvar_define", "data_type": "u32", "variable": "co", "size": 3}, {"//": "Parallel Rz(1)"}, {"qop": "RZ", "angles": [[1.0], "pi"], "args": [["q", 0], ["q", 1]]}, {"//": "Parallel PhasedX(0.5, 0.5)"}, {"qop": "R1XY", "angles": [[0.5, 0.5], "pi"], "args": [["q", 0], ["q", 1]]}, {"//": "Parallel RZ"}, {"block": "qparallel", "ops": [{"qop": "RZ", "angles": [[0.5], "pi"], "args": [["q", 0]]}, {"qop": "RZ", "angles": [[1.5], "pi"], "args": [["q", 1]]}]}, {"//": "ZZPhase(0.5) q[1], q[0];"}, {"qop": "RZZ", "angles": [[0.5], "pi"], "args": [[["q", 1], ["q", 0]]]}, {"mop": "Transport", "duration": [0.0, "ms"]}, {"//": "Parallel RZ"}, {"block": "qparallel", "ops": [{"qop": "RZ", "angles": [[1.5], "pi"], "args": [["q", 0]]}, {"qop": "RZ", "angles": [[0.5], "pi"], "args": [["q", 1]]}]}, {"qop": "Measure", "args": [["q", 0], ["q", 1]], "returns": [["cr", 0], ["cr", 1]]}, {"mop": "Transport", "duration": [0.0, "ms"]}, {"//": "CopyBits cr[0], cr[1], cr[2], cs[0], cs[1], cs[2];"}, {"cop": "=", "returns": [["cs", 0], ["cs", 1], ["cs", 2]], "args": [["cr", 0], ["cr", 1], ["cr", 2]]}, {"mop": "Transport", "duration": [0.0, "ms"]}, {"//": "WASM function=add args=['cr', 'cs'] returns=['co']"}, {"cop": "ffcall", "function": "add", "args": ["cr", "cs"], "metadata": {"ff_object": "WASM module uid: 48b455b2aba63187d5f1720a71762c3f5cfbd359c309c1fa91e5d7027b2e111a"}, "returns": ["co"]}, {"mop": "Transport", "duration": [0.0, "ms"]}]}

PECOS results:
Traceback (most recent call last):
  File "/Users/kartik/GH/CQCL/pytket-phir/.venv/bin/phirc", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/kartik/GH/CQCL/pytket-phir/.venv/lib/python3.12/site-packages/pytket/phir/cli.py", line 84, in main
    print(HybridEngine(qsim="state-vector").run(program=phir, shots=10))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kartik/GH/CQCL/pytket-phir/.venv/lib/python3.12/site-packages/pecos/engines/hybrid_engine.py", line 160, in run
    self.initialize_sim_components(program, foreign_object)
  File "/Users/kartik/GH/CQCL/pytket-phir/.venv/lib/python3.12/site-packages/pecos/engines/hybrid_engine.py", line 101, in initialize_sim_components
    num_qubits = self.cinterp.init(program, foreign_object)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kartik/GH/CQCL/pytket-phir/.venv/lib/python3.12/site-packages/pecos/classical_interpreters/phir_classical_interpreter.py", line 95, in init
    self.check_ffc(self.program.foreign_func_calls, self.foreign_obj)
  File "/Users/kartik/GH/CQCL/pytket-phir/.venv/lib/python3.12/site-packages/pecos/classical_interpreters/phir_classical_interpreter.py", line 103, in check_ffc
    func_names = set(fobj.get_funcs())
                     ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_funcs'

Do we know what may be going on? cc: @qciaran

@qciaran
Copy link
Collaborator

qciaran commented Jan 23, 2024

Do we know what may be going on? cc: @qciaran

My guess you are trying to run PHIR that is calling Wasm but not supplying the Wasm to PECOS via a "ForeignObj". It would be something like:

from pecos.foreign_objects.wasmtime import WasmtimeObj
wasm_obj = WasmtimeObj("./wasm/add.wasm")  # input can be file path to .wat or .wasm, or bytes
HybridEngine(...).run(phir, foreign_object=wasm_obj, ...) 

It might be good for me to make the run() interface a little nice by supplying a wasm_bytes option and it do all the work of preparing the object for you.

You can see some example useage here: https://github.com/PECOS-packages/PECOS/blob/566029d49f57da5510b4e443f1fb13964aa273ec/tests/integration/test_phir.py#L64


from argparse import ArgumentParser
from importlib.metadata import version

from pecos.engines.hybrid_engine import HybridEngine # type:ignore [import-not-found]
from pecos.foreign_objects.wasmtime import WasmtimeObj # type:ignore [import-not-found]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just sent a PR to pecos at PECOS-packages/PECOS#37 to avoid these type ignores.

Copy link
Member

@qartik qartik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good!

Copy link
Collaborator

@qciaran qciaran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working for me/LGTM

@neal-erickson neal-erickson merged commit a199f3c into main Jan 23, 2024
6 checks passed
@neal-erickson neal-erickson deleted the issue-50-wasm-support branch January 23, 2024 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Wasm support
4 participants