diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 14e7700f..579d1774 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -28,8 +28,8 @@ shell by setting up [direnv](https://devenv.sh/automatic-shell-activation/). To setup the environment manually you will need: -- Just: https://just.systems/ -- Rust `>=1.75`: https://www.rust-lang.org/tools/install +- Just: +- Rust `>=1.75`: - uv `>=0.3`: docs.astral.sh/uv/getting-started/installation Once you have these installed, install the required python dependencies and setup pre-commit hooks with: @@ -101,6 +101,7 @@ line-by-line coverage report on [codecov](https://app.codecov.io/gh/CQCL/tket2/commits?branch=All%20branches). To run the coverage checks locally, first install `cargo-llvm-cov`. + ```bash cargo install cargo-llvm-cov ``` diff --git a/tket2-exts/README.md b/tket2-exts/README.md index d3cb6d81..fdba8ec4 100644 --- a/tket2-exts/README.md +++ b/tket2-exts/README.md @@ -12,8 +12,7 @@ This is an auxiliary Python package containing HUGR extension definitions for `t operations and types. This package is intended to be used as an internal dependency for `tket2`. -See https://pypi.org/project/tket2/ for the main package. - +See for the main package. ## Install @@ -29,9 +28,8 @@ See [DEVELOPMENT.md] information on how to develop and contribute to this packag [DEVELOPMENT.md]: https://github.com/CQCL/tket2/blob/main/DEVELOPMENT.md - ## License -This project is licensed under Apache License, Version 2.0 ([LICENCE][] or http://www.apache.org/licenses/LICENSE-2.0). +This project is licensed under Apache License, Version 2.0 ([LICENCE][] or ). [LICENCE]: https://github.com/CQCL/tket2/blob/main/LICENCE diff --git a/tket2-exts/src/tket2_exts/__init__.py b/tket2-exts/src/tket2_exts/__init__.py index 448c6a3a..e2574d4d 100644 --- a/tket2-exts/src/tket2_exts/__init__.py +++ b/tket2-exts/src/tket2_exts/__init__.py @@ -26,6 +26,11 @@ def qsystem() -> Extension: return load_extension("tket2.qsystem") +@functools.cache +def qsystem_utils() -> Extension: + return load_extension("tket2.qsystem.utils") + + @functools.cache def quantum() -> Extension: return load_extension("tket2.quantum") diff --git a/tket2-exts/src/tket2_exts/data/tket2/qsystem/utils.json b/tket2-exts/src/tket2_exts/data/tket2/qsystem/utils.json new file mode 100644 index 00000000..047e62a4 --- /dev/null +++ b/tket2-exts/src/tket2_exts/data/tket2/qsystem/utils.json @@ -0,0 +1,38 @@ +{ + "version": "0.1.0", + "name": "tket2.qsystem.utils", + "runtime_reqs": [ + "prelude" + ], + "types": {}, + "values": {}, + "operations": { + "GetCurrentShot": { + "extension": "tket2.qsystem.utils", + "name": "GetCurrentShot", + "description": "Get current shot number.", + "signature": { + "params": [], + "body": { + "input": [], + "output": [ + { + "t": "Opaque", + "extension": "arithmetic.int.types", + "id": "int", + "args": [ + { + "tya": "BoundedNat", + "n": 6 + } + ], + "bound": "C" + } + ], + "runtime_reqs": [] + } + }, + "binary": false + } + } +} diff --git a/tket2-hseries/README.md b/tket2-hseries/README.md index 7f7bc2cf..9ba562e3 100644 --- a/tket2-hseries/README.md +++ b/tket2-hseries/README.md @@ -26,7 +26,7 @@ See [DEVELOPMENT.md][] for instructions on setting up the development environmen ## License -This project is licensed under Apache License, Version 2.0 ([LICENSE][] or http://www.apache.org/licenses/LICENSE-2.0). +This project is licensed under Apache License, Version 2.0 ([LICENSE][] or ). [msrv]: https://img.shields.io/badge/rust-1.75.0%2B-blue.svg [LICENSE]: https://github.com/CQCL/tket2/blob/main/LICENCE diff --git a/tket2-hseries/src/bin/tket2-hseries.rs b/tket2-hseries/src/bin/tket2-hseries.rs index e7ef0113..48cf2f52 100644 --- a/tket2-hseries/src/bin/tket2-hseries.rs +++ b/tket2-hseries/src/bin/tket2-hseries.rs @@ -14,6 +14,7 @@ fn main() { tket2_hseries::extension::futures::EXTENSION.to_owned(), tket2_hseries::extension::result::EXTENSION.to_owned(), tket2_hseries::extension::wasm::EXTENSION.to_owned(), + tket2_hseries::extension::utils::EXTENSION.to_owned(), ]); args.run_dump(®); diff --git a/tket2-hseries/src/extension.rs b/tket2-hseries/src/extension.rs index d545a6ca..de809a56 100644 --- a/tket2-hseries/src/extension.rs +++ b/tket2-hseries/src/extension.rs @@ -2,4 +2,5 @@ pub mod futures; pub mod qsystem; pub mod result; +pub mod utils; pub mod wasm; diff --git a/tket2-hseries/src/extension/utils.rs b/tket2-hseries/src/extension/utils.rs new file mode 100644 index 00000000..73dce3d3 --- /dev/null +++ b/tket2-hseries/src/extension/utils.rs @@ -0,0 +1,154 @@ +//! This module contains utility functions for Quantinuum systems. + +use std::sync::{Arc, Weak}; + +use derive_more::derive::Display; +use hugr::{ + builder::{BuildError, Dataflow}, + extension::{ + prelude::UnwrapBuilder, + simple_op::{try_from_name, MakeOpDef, MakeRegisteredOp}, + ExtensionId, ExtensionRegistry, ExtensionSet, OpDef, SignatureFunc, Version, PRELUDE, + }, + std_extensions::arithmetic::int_types::int_type, + type_row, + types::Signature, + Extension, Wire, +}; +use lazy_static::lazy_static; +use strum::{EnumIter, EnumString, IntoStaticStr}; + +/// The extension ID for the utils extension. +pub const EXTENSION_ID: ExtensionId = ExtensionId::new_unchecked("tket2.qsystem.utils"); +/// The version of the "tket2.qsystem.utils" extension. +pub const EXTENSION_VERSION: Version = Version::new(0, 1, 0); + +lazy_static! { + /// The "tket2.qsystem.utils" extension. + pub static ref EXTENSION: Arc = { + Extension::new_arc(EXTENSION_ID, EXTENSION_VERSION, |ext, ext_ref| { + ext.add_requirements(ExtensionSet::from_iter([ + PRELUDE.name(), + ].into_iter().cloned())); + UtilsOp::load_all_ops( ext, ext_ref).unwrap(); + }) + }; + + /// Extension registry including the "tket2.qsystem.utils" extension and + /// dependencies. + pub static ref REGISTRY: ExtensionRegistry = ExtensionRegistry::new([ + EXTENSION.to_owned(), + PRELUDE.to_owned(), + ]); +} + +#[derive( + Clone, + Copy, + Debug, + serde::Serialize, + serde::Deserialize, + Hash, + PartialEq, + Eq, + PartialOrd, + Ord, + EnumIter, + IntoStaticStr, + EnumString, + Display, +)] +/// The operations provided by the utils extension. +pub enum UtilsOp { + /// fn get_current_shot() -> usize + GetCurrentShot, +} + +impl MakeOpDef for UtilsOp { + fn init_signature(&self, _extension_ref: &std::sync::Weak) -> SignatureFunc { + match self { + UtilsOp::GetCurrentShot => Signature::new(type_row![], int_type(6)), + } + .into() + } + + fn from_def(op_def: &OpDef) -> Result { + try_from_name(op_def.name(), op_def.extension_id()) + } + + fn extension(&self) -> ExtensionId { + EXTENSION_ID + } + + fn extension_ref(&self) -> std::sync::Weak { + Arc::downgrade(&EXTENSION) + } + + fn description(&self) -> String { + match self { + UtilsOp::GetCurrentShot => "Get current shot number.", + } + .to_string() + } +} + +impl MakeRegisteredOp for UtilsOp { + fn extension_id(&self) -> ExtensionId { + EXTENSION_ID + } + + fn extension_ref(&self) -> Weak { + Arc::downgrade(&EXTENSION) + } +} + +/// An extension trait for [Dataflow] providing methods to add +/// "tket2.qsystem.utils" operations. +pub trait UtilsOpBuilder: Dataflow + UnwrapBuilder { + /// Add a "tket2.qsystem.utils.GetCurrentShot" op. + fn add_get_current_shot(&mut self) -> Result { + Ok(self + .add_dataflow_op(UtilsOp::GetCurrentShot, [])? + .out_wire(0)) + } +} + +impl UtilsOpBuilder for D {} + +#[cfg(test)] +mod test { + use std::sync::Arc; + + use hugr::builder::{DataflowHugr, FunctionBuilder}; + use hugr::ops::NamedOp; + use strum::IntoEnumIterator; + + use super::*; + + fn get_opdef(op: impl NamedOp) -> Option<&'static Arc> { + EXTENSION.get_op(&op.name()) + } + + #[test] + fn create_extension() { + assert_eq!(EXTENSION.name(), &EXTENSION_ID); + + for o in UtilsOp::iter() { + assert_eq!(UtilsOp::from_def(get_opdef(o).unwrap()), Ok(o)); + } + } + + #[test] + fn get_current_shot() { + let hugr = { + let mut func_builder = FunctionBuilder::new( + "get_current_shot", + Signature::new(vec![], vec![int_type(6)]), + ) + .unwrap(); + let shot = func_builder.add_get_current_shot().unwrap(); + func_builder.finish_hugr_with_outputs([shot]).unwrap() + }; + hugr.validate().unwrap() + } +} diff --git a/tket2-py/tket2/extensions/__init__.py b/tket2-py/tket2/extensions/__init__.py index 58354f40..fe780d94 100644 --- a/tket2-py/tket2/extensions/__init__.py +++ b/tket2-py/tket2/extensions/__init__.py @@ -1,4 +1,4 @@ -from tket2_exts import rotation, futures, qsystem, quantum, result +from tket2_exts import rotation, futures, qsystem, qsystem_utils, quantum, result -__all__ = ["rotation", "futures", "qsystem", "quantum", "result"] +__all__ = ["rotation", "futures", "qsystem", "qsystem_utils", "quantum", "result"] diff --git a/uv.lock b/uv.lock index 7b6d1401..8c2b94fb 100644 --- a/uv.lock +++ b/uv.lock @@ -7,9 +7,7 @@ members = [ "tket2-eccs", "tket2-exts", ] - -[manifest.dependency-groups] -dev = [ +requirements = [ { name = "graphviz", specifier = ">=0.20,<0.21" }, { name = "hypothesis", specifier = ">=6.111.1,<7" }, { name = "maturin", specifier = ">=1.7.0,<2" },