From f3e4098af78733c22730bc394b52e32755b7edf0 Mon Sep 17 00:00:00 2001 From: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:12:22 +0000 Subject: [PATCH] Allow passing of WASM to emulator (#18) --- pyproject.toml | 2 +- src/pytket_pecos/emulator.py | 8 +++++- test/test_emulator.py | 16 +++++++++++- test/wasm/add1.c | 5 ++++ test/wasm/add1.wasm | Bin 0 -> 398 bytes test/wasm/add1.wast | 48 +++++++++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 test/wasm/add1.c create mode 100755 test/wasm/add1.wasm create mode 100644 test/wasm/add1.wast diff --git a/pyproject.toml b/pyproject.toml index 948cf79..d947098 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi" [project] name = "pytket_pecos" -version = "0.1.10" +version = "0.1.11" description = "This package enables emulation of pytket circuits using the PECOS emulator." authors = [{name = "Alec Edgington", email = "alec.edgington@quantinuum.com"}] license = {file = "LICENSE"} diff --git a/src/pytket_pecos/emulator.py b/src/pytket_pecos/emulator.py index 0ffe870..80eed7b 100644 --- a/src/pytket_pecos/emulator.py +++ b/src/pytket_pecos/emulator.py @@ -2,9 +2,11 @@ from typing import Optional from pecos.engines.hybrid_engine import HybridEngine # type: ignore from pecos.error_models.error_model_abc import ErrorModel # type: ignore +from pecos.foreign_objects.wasmtime import WasmtimeObj from pytket.circuit import Circuit from pytket.phir.api import pytket_to_phir from pytket.utils.outcomearray import OutcomeArray +from pytket.wasm import WasmFileHandler def is_reglike(units): @@ -20,6 +22,7 @@ class Emulator: def __init__( self, circuit: Circuit, + wasm: Optional[WasmFileHandler] = None, error_model: Optional[ErrorModel] = None, qsim: str = "stabilizer", seed: Optional[int] = None, @@ -28,11 +31,14 @@ def __init__( raise ValueError("Circuit contains units that do not belong to a register.") self.phir = pytket_to_phir(circuit) + self.foreign_object = None if wasm is None else WasmtimeObj(wasm._wasm_file) self.engine = HybridEngine(qsim=qsim, error_model=error_model) self.engine.use_seed(seed) def run(self, n_shots) -> OutcomeArray: - results = self.engine.run(self.phir, shots=n_shots) + results = self.engine.run( + self.phir, foreign_object=self.foreign_object, shots=n_shots + ) c_regs = sorted(results.keys()) readouts = [] for i in range(n_shots): diff --git a/test/test_emulator.py b/test/test_emulator.py index 964dca8..b0fe3f3 100644 --- a/test/test_emulator.py +++ b/test/test_emulator.py @@ -1,7 +1,9 @@ +from pathlib import Path import unittest from pecos.error_models.generic_error_model import GenericErrorModel # type: ignore -from pytket.circuit import Circuit +from pytket.circuit import Circuit, Qubit +from pytket.wasm import WasmFileHandler from pytket_pecos import Emulator @@ -81,6 +83,18 @@ def test_setbits(self): result = emu.run(n_shots=1).to_intlist()[0] assert result == 0b110110 + def test_wasm(self): + wasmfile = WasmFileHandler(str(Path(__file__).parent / "wasm" / "add1.wasm")) + c = Circuit(1) + a = c.add_c_register("a", 8) + c.add_c_setreg(23, a) + c.add_wasm_to_reg("add_one", wasmfile, [a], [a]) + c.X(0) + c.Measure(Qubit(0), a[0]) + emu = Emulator(c, wasm=wasmfile) + result = emu.run(n_shots=1).to_intlist()[0] + assert result == 0b10011000 + if __name__ == "__main__": unittest.main() diff --git a/test/wasm/add1.c b/test/wasm/add1.c new file mode 100644 index 0000000..5346772 --- /dev/null +++ b/test/wasm/add1.c @@ -0,0 +1,5 @@ +void init() {} + +int add_one(int n) { + return n + 1; +} diff --git a/test/wasm/add1.wasm b/test/wasm/add1.wasm new file mode 100755 index 0000000000000000000000000000000000000000..2e58640cdc8766b71b80fc2575e15a31bcc32616 GIT binary patch literal 398 zcmZvXPfNo<5XEP9^T#%kT0g;tUIb}rP{e}>`4FC`o9xooZgxvHL3&D${n*9^PdbNT ze(%8>9!Os!0N{je05;fT&jUVi$Prld824D5FG12nalZMpM+1IzOyUbpqgvOlIWd?M zeGSo6Nn@yLUE=|Qz1_Efu~dqj)xc6B