-
Notifications
You must be signed in to change notification settings - Fork 2
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
Conversation
Co-authored-by: Kartik Singhal <[email protected]>
There was a problem hiding this 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.
I primarily use |
I get what I expect when running a simulation after generating PHIR from using |
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? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
There was a problem hiding this 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.
@qartik tket_opt_level fix was already in place due to CLI changes. |
|
||
wasm_bytes = get_wat_as_wasm_bytes(WatFile.add) | ||
|
||
wasm_uid = hashlib.sha256(base64.b64encode(wasm_bytes)).hexdigest() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@neal-erickson I referenced https://github.com/CQCL/tket/blob/6906704b0ad64d077dff5c71454652926f91ee12/pytket/pytket/wasm/wasm.py#L77-L81 to generate this wasm_id
|
||
phir = json.loads(phir_str) | ||
|
||
expected_metadata = {"ff_object": (f"WASM module uid: {w!s}")} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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 |
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 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] |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking good!
There was a problem hiding this 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
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.