Skip to content

Commit

Permalink
refactor!: update to hugr 0.14 (#700)
Browse files Browse the repository at this point in the history
Awaiting release



BREAKING CHANGE: Extension definitions and registries use `Arc` for
sharing
  • Loading branch information
ss2165 authored Nov 28, 2024
1 parent 92cb943 commit 7d3e5f5
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 159 deletions.
189 changes: 92 additions & 97 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ missing_docs = "warn"
[patch.crates-io]

# Uncomment to use unreleased versions of hugr
#hugr-core = { git = "https://github.com/CQCL/hugr.git" }
#hugr = { git = "https://github.com/CQCL/hugr.git" }
#hugr-cli = { git = "https://github.com/CQCL/hugr.git" }
hugr-core = { git = "https://github.com/CQCL/hugr.git" }
hugr = { git = "https://github.com/CQCL/hugr.git" }
hugr-cli = { git = "https://github.com/CQCL/hugr.git" }

[workspace.dependencies]

Expand Down
20 changes: 13 additions & 7 deletions tket2-hseries/src/extension/futures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
//! `Future<t>` is a linear type representing a value that will be available in
//! the future. It can be consumed by `Read`, returning a `t`. It can be
//! duplicated by `Dup`, and discarded with `Free`.
use std::sync::{Arc, Weak};

use hugr::{
builder::{BuildError, Dataflow},
extension::{
Expand All @@ -29,12 +31,12 @@ pub const EXTENSION_VERSION: Version = Version::new(0, 1, 0);

lazy_static! {
/// The "tket2.futures" extension.
pub static ref EXTENSION: Extension = {
let mut ext = Extension::new(EXTENSION_ID, EXTENSION_VERSION);
let _ = add_future_type_def(&mut ext).unwrap();
pub static ref EXTENSION: Arc<Extension> = {
Extension::new_arc(EXTENSION_ID, EXTENSION_VERSION, |ext, ext_ref| {
let _ = add_future_type_def(ext, ext_ref.clone()).unwrap();

FutureOpDef::load_all_ops(&mut ext).unwrap();
ext
FutureOpDef::load_all_ops( ext, ext_ref).unwrap();
})
};

/// Extension registry including the "tket2.futures" extension.
Expand All @@ -46,12 +48,16 @@ lazy_static! {
pub static ref FUTURE_TYPE_NAME: SmolStr = SmolStr::new_inline("Future");
}

fn add_future_type_def(ext: &mut Extension) -> Result<&TypeDef, ExtensionBuildError> {
fn add_future_type_def(
ext: &mut Extension,
extension_ref: Weak<Extension>,
) -> Result<&TypeDef, ExtensionBuildError> {
ext.add_type(
FUTURE_TYPE_NAME.to_owned(),
vec![TypeBound::Any.into()],
"A value that is computed asynchronously".into(),
TypeBound::Any.into(),
&extension_ref,
)
}

Expand Down Expand Up @@ -119,7 +125,7 @@ impl MakeOpDef for FutureOpDef {
}

fn from_def(op_def: &OpDef) -> Result<Self, hugr::extension::simple_op::OpLoadError> {
try_from_name(op_def.name(), op_def.extension())
try_from_name(op_def.name(), op_def.extension_id())
}

fn description(&self) -> String {
Expand Down
21 changes: 12 additions & 9 deletions tket2-hseries/src/extension/hseries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//! In the case of lazy operations,
//! laziness is represented by returning `tket2.futures.Future` classical
//! values. Qubits are never lazy.
use std::sync::Arc;

use hugr::{
builder::{BuildError, Dataflow},
extension::{
Expand Down Expand Up @@ -39,14 +41,15 @@ pub const EXTENSION_VERSION: Version = Version::new(0, 1, 0);

lazy_static! {
/// The "tket2.hseries" extension.
pub static ref EXTENSION: Extension = {
let mut ext = Extension::new(EXTENSION_ID, EXTENSION_VERSION).with_reqs(ExtensionSet::from_iter([
futures::EXTENSION.name(),
PRELUDE.name(),
FLOAT_TYPES.name(),
].into_iter().cloned()));
HSeriesOp::load_all_ops(&mut ext).unwrap();
ext
pub static ref EXTENSION: Arc<Extension> = {
Extension::new_arc(EXTENSION_ID, EXTENSION_VERSION, |ext, ext_ref| {
ext.add_requirements(ExtensionSet::from_iter([
futures::EXTENSION.name(),
PRELUDE.name(),
FLOAT_TYPES.name(),
].into_iter().cloned()));
HSeriesOp::load_all_ops( ext, ext_ref).unwrap();
})
};

/// Extension registry including the "tket2.hseries" extension and
Expand Down Expand Up @@ -108,7 +111,7 @@ impl MakeOpDef for HSeriesOp {
}

fn from_def(op_def: &OpDef) -> Result<Self, hugr::extension::simple_op::OpLoadError> {
try_from_name(op_def.name(), op_def.extension())
try_from_name(op_def.name(), op_def.extension_id())
}

fn extension(&self) -> ExtensionId {
Expand Down
2 changes: 1 addition & 1 deletion tket2-hseries/src/extension/hseries/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub fn check_lowered(hugr: &impl HugrView) -> Result<(), Vec<Node>> {
.filter_map(|node| {
let optype = hugr.get_optype(node);
optype.as_extension_op().and_then(|ext| {
(ext.def().extension() == &tket2::extension::TKET2_EXTENSION_ID).then_some(node)
(ext.def().extension_id() == &tket2::extension::TKET2_EXTENSION_ID).then_some(node)
})
})
.collect();
Expand Down
13 changes: 8 additions & 5 deletions tket2-hseries/src/extension/result.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! This module defines the Hugr extension used to represent result reporting operations,
//! with static string tags.
//!
use std::sync::Arc;

use hugr::types::Signature;
use hugr::{
builder::{BuildError, Dataflow},
Expand Down Expand Up @@ -35,10 +37,11 @@ pub const EXTENSION_VERSION: Version = Version::new(0, 1, 0);

lazy_static! {
/// The "tket2.result" extension.
pub static ref EXTENSION: Extension = {
let mut ext = Extension::new(EXTENSION_ID, EXTENSION_VERSION).with_reqs(ExtensionSet::from_iter([INT_EXTENSION_ID, FLOAT_EXTENSION_ID]));
ResultOpDef::load_all_ops(&mut ext).unwrap();
ext
pub static ref EXTENSION: Arc<Extension> = {
Extension::new_arc(EXTENSION_ID, EXTENSION_VERSION, |ext, ext_ref| {
ext.add_requirements(ExtensionSet::from_iter([INT_EXTENSION_ID, FLOAT_EXTENSION_ID]));
ResultOpDef::load_all_ops(ext, ext_ref).unwrap();
})
};

/// Extension registry including the "tket2.result" extension and
Expand Down Expand Up @@ -194,7 +197,7 @@ impl MakeOpDef for ResultOpDef {
}

fn from_def(op_def: &OpDef) -> Result<Self, hugr::extension::simple_op::OpLoadError> {
try_from_name(op_def.name(), op_def.extension())
try_from_name(op_def.name(), op_def.extension_id())
}

fn extension(&self) -> ExtensionId {
Expand Down
10 changes: 5 additions & 5 deletions tket2/src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub struct Circuit<T = Hugr> {
/// Wrapped in an Arc to allow sharing between circuits, specially for borrowed circuits.
///
/// Defaults to an standard set of quantum extensions and Hugr's std set.
required_extensions: Option<Arc<Vec<Extension>>>,
required_extensions: Option<Vec<Arc<Extension>>>,
}

impl<T: Default + HugrView> Default for Circuit<T> {
Expand Down Expand Up @@ -94,7 +94,7 @@ lazy_static! {
///
/// We should be able to drop this once hugrs embed their required extensions.
/// See https://github.com/CQCL/hugr/issues/1613
static ref DEFAULT_REQUIRED_EXTENSIONS: Vec<Extension> = extension::REGISTRY.iter().map(|(_, ext)| ext.clone()).collect();
static ref DEFAULT_REQUIRED_EXTENSIONS: Vec<Arc<Extension>> = extension::REGISTRY.iter().map(|(_, ext)| ext.to_owned()).collect();
}
/// The [IGNORED_EXTENSION_OPS] definition depends on the buggy behaviour of [`NamedOp::name`], which returns bare names instead of scoped names on some cases.
/// Once this test starts failing it should be time to drop the `format!("prelude.{}", ...)`.
Expand Down Expand Up @@ -160,7 +160,7 @@ impl<T: HugrView> Circuit<T> {
/// Note: This API is not currently public. We expect hugrs to embed their required extensions in the future,
/// at which point this method will be removed.
/// See https://github.com/CQCL/hugr/issues/1613
pub(crate) fn required_extensions(&self) -> &[Extension] {
pub(crate) fn required_extensions(&self) -> &[Arc<Extension>] {
self.required_extensions
.as_deref()
.unwrap_or_else(|| &DEFAULT_REQUIRED_EXTENSIONS)
Expand All @@ -175,8 +175,8 @@ impl<T: HugrView> Circuit<T> {
/// See https://github.com/CQCL/hugr/issues/1613
pub(crate) fn set_required_extensions(
&mut self,
extensions: Arc<Vec<Extension>>,
) -> Option<Arc<Vec<Extension>>> {
extensions: Vec<Arc<Extension>>,
) -> Option<Vec<Arc<Extension>>> {
mem::replace(&mut self.required_extensions, Some(extensions))
}

Expand Down
36 changes: 18 additions & 18 deletions tket2/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//!
//! This includes a extension for the opaque TKET1 operations.
use std::sync::Arc;

use crate::serialize::pytket::OpaqueTk1Op;
use crate::Tk2Op;
use hugr::extension::simple_op::MakeOpDef;
Expand Down Expand Up @@ -40,17 +42,15 @@ pub static ref TKET1_OP_PAYLOAD : CustomType =
TKET1_EXTENSION.get_type(&TKET1_PAYLOAD_NAME).unwrap().instantiate([]).unwrap();

/// The TKET1 extension, containing the opaque TKET1 operations.
pub static ref TKET1_EXTENSION: Extension = {
let mut res = Extension::new(TKET1_EXTENSION_ID, TKET1_EXTENSION_VERSION);

let tket1_op_payload = TypeParam::String;
res.add_op(
TKET1_OP_NAME,
"An opaque TKET1 operation.".into(),
Tk1Signature([tket1_op_payload])
).unwrap();

res
pub static ref TKET1_EXTENSION: Arc<Extension> = {
Extension::new_arc(TKET1_EXTENSION_ID, TKET1_EXTENSION_VERSION, |res, ext_ref| {
res.add_op(
TKET1_OP_NAME,
"An opaque TKET1 operation.".into(),
Tk1Signature([TypeParam::String]),
ext_ref
).unwrap();
})
};

/// Extension registry including the prelude, std, TKET1, and Tk2Ops extensions.
Expand Down Expand Up @@ -93,11 +93,11 @@ pub const TKET2_EXTENSION_ID: ExtensionId = ExtensionId::new_unchecked("tket2.qu
pub const TKET2_EXTENSION_VERSION: Version = Version::new(0, 1, 0);

lazy_static! {
/// The extension definition for TKET2 ops and types.
pub static ref TKET2_EXTENSION: Extension = {
let mut e = Extension::new(TKET2_EXTENSION_ID, TKET2_EXTENSION_VERSION);
Tk2Op::load_all_ops(&mut e).expect("add fail");
SympyOpDef.add_to_extension(&mut e).unwrap();
e
};
/// The extension definition for TKET2 ops and types.
pub static ref TKET2_EXTENSION: Arc<Extension> = {
Extension::new_arc(TKET2_EXTENSION_ID, TKET2_EXTENSION_VERSION, |res, ext_ref| {
Tk2Op::load_all_ops(res, ext_ref).expect("add_fail");
SympyOpDef.add_to_extension(res, ext_ref).unwrap();
})
};
}
18 changes: 10 additions & 8 deletions tket2/src/extension/rotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use hugr::{
};
use smol_str::SmolStr;
use std::f64::consts::PI;
use std::sync::{Arc, Weak};
use strum::{EnumIter, EnumString, IntoStaticStr};

use lazy_static::lazy_static;
Expand All @@ -22,11 +23,11 @@ pub const ROTATION_EXTENSION_VERSION: Version = Version::new(0, 1, 0);

lazy_static! {
/// The extension definition for TKET2 rotation type and ops.
pub static ref ROTATION_EXTENSION: Extension = {
let mut e = Extension::new(ROTATION_EXTENSION_ID, ROTATION_EXTENSION_VERSION);
add_to_extension(&mut e);
e
};
pub static ref ROTATION_EXTENSION: Arc<Extension> = {
Extension::new_arc(ROTATION_EXTENSION_ID, ROTATION_EXTENSION_VERSION, |e, extension_ref| {
add_to_extension(e, extension_ref);
}
)};
}

/// Identifier for the rotation type.
Expand Down Expand Up @@ -131,7 +132,7 @@ impl MakeOpDef for RotationOp {
where
Self: Sized,
{
hugr::extension::simple_op::try_from_name(op_def.name(), op_def.extension())
hugr::extension::simple_op::try_from_name(op_def.name(), op_def.extension_id())
}

fn signature(&self) -> hugr::extension::SignatureFunc {
Expand Down Expand Up @@ -188,17 +189,18 @@ impl MakeRegisteredOp for RotationOp {
}
}

pub(super) fn add_to_extension(extension: &mut Extension) {
pub(super) fn add_to_extension(extension: &mut Extension, extension_ref: &Weak<Extension>) {
extension
.add_type(
ROTATION_TYPE_ID,
vec![],
"rotation type expressed as number of half turns".to_owned(),
TypeBound::Copyable.into(),
extension_ref,
)
.unwrap();

RotationOp::load_all_ops(extension).expect("add fail");
RotationOp::load_all_ops(extension, extension_ref).expect("add fail");
}

/// An extension trait for [Dataflow] providing methods to add
Expand Down
2 changes: 1 addition & 1 deletion tket2/src/extension/sympy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl MakeOpDef for SympyOpDef {
where
Self: Sized,
{
try_from_name(op_def.name(), op_def.extension())
try_from_name(op_def.name(), op_def.extension_id())
}

fn signature(&self) -> hugr::extension::SignatureFunc {
Expand Down
6 changes: 3 additions & 3 deletions tket2/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl MakeOpDef for Tk2Op {
}

fn from_def(op_def: &OpDef) -> Result<Self, hugr::extension::simple_op::OpLoadError> {
try_from_name(op_def.name(), op_def.extension())
try_from_name(op_def.name(), op_def.extension_id())
}
}

Expand Down Expand Up @@ -190,7 +190,7 @@ pub(crate) fn match_symb_const_op(op: &OpType) -> Option<String> {
};

if let OpType::ExtensionOp(e) = op {
if e.def().name() == &SYM_OP_ID && e.def().extension() == &EXTENSION_ID {
if e.def().name() == &SYM_OP_ID && e.def().extension_id() == &EXTENSION_ID {
Some(symbol_from_typeargs(e.args()))
} else {
None
Expand Down Expand Up @@ -276,7 +276,7 @@ pub(crate) mod test {

let ext_op = op.into_extension_op();
assert_eq!(ext_op.args(), &[]);
assert_eq!(ext_op.def().extension(), &EXTENSION_ID);
assert_eq!(ext_op.def().extension_id(), &EXTENSION_ID);
let name = ext_op.def().name();
assert_eq!(Tk2Op::from_str(name), Ok(op));
}
Expand Down
1 change: 1 addition & 0 deletions tket2/src/portmatching/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl CircuitPattern {
.map(|p| {
hugr.linked_ports(out, p)
.exactly_one()
.ok()
.expect("invalid circuit")
})
.collect_vec();
Expand Down
3 changes: 1 addition & 2 deletions tket2/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
pub mod pytket;

use std::io;
use std::sync::Arc;

use hugr::extension::ExtensionRegistryError;
use hugr::hugr::ValidationError;
Expand Down Expand Up @@ -107,7 +106,7 @@ impl Circuit<Hugr> {

let (_module_idx, mut circ) = find_function_in_modules(modules, function_name.as_ref())?;
if !extensions.is_empty() {
circ.set_required_extensions(Arc::new(extensions));
circ.set_required_extensions(extensions);
}
Ok(circ)
}
Expand Down

0 comments on commit 7d3e5f5

Please sign in to comment.