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 0000000..2e58640 Binary files /dev/null and b/test/wasm/add1.wasm differ diff --git a/test/wasm/add1.wast b/test/wasm/add1.wast new file mode 100644 index 0000000..b9b47f3 --- /dev/null +++ b/test/wasm/add1.wast @@ -0,0 +1,48 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32) (result i32))) + (func $__wasm_call_ctors (type 0)) + (func $init (type 0) + return) + (func $add_one (type 1) (param i32) (result i32) + (local i32 i32 i32 i32 i32 i32) + global.get $__stack_pointer + local.set 1 + i32.const 16 + local.set 2 + local.get 1 + local.get 2 + i32.sub + local.set 3 + local.get 3 + local.get 0 + i32.store offset=12 + local.get 3 + i32.load offset=12 + local.set 4 + i32.const 1 + local.set 5 + local.get 4 + local.get 5 + i32.add + local.set 6 + local.get 6 + return) + (memory (;0;) 2) + (global $__stack_pointer (mut i32) (i32.const 66560)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 1024)) + (global (;3;) i32 (i32.const 1024)) + (global (;4;) i32 (i32.const 66560)) + (global (;5;) i32 (i32.const 0)) + (global (;6;) i32 (i32.const 1)) + (export "memory" (memory 0)) + (export "__wasm_call_ctors" (func $__wasm_call_ctors)) + (export "init" (func $init)) + (export "add_one" (func $add_one)) + (export "__dso_handle" (global 1)) + (export "__data_end" (global 2)) + (export "__global_base" (global 3)) + (export "__heap_base" (global 4)) + (export "__memory_base" (global 5)) + (export "__table_base" (global 6)))