Skip to content

Commit

Permalink
feat!: rename extension_reqs to runtime_reqs (#1776)
Browse files Browse the repository at this point in the history
Closes #1734
CustomConst::extension_reqs not renamed because they still refer to the
extensions where they are defined. this should be updated to references
to match ops and types #1775

BREAKING CHANGE: `extension_reqs` field in FunctionType and Extension
renamed to `runtime_reqs`
  • Loading branch information
ss2165 authored Dec 12, 2024
1 parent b63aabc commit 5f5bce4
Show file tree
Hide file tree
Showing 53 changed files with 326 additions and 336 deletions.
4 changes: 2 additions & 2 deletions hugr-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Please read the [API documentation here][].
## Experimental Features

- `extension_inference`:
Experimental feature which allows automatic inference of extension usages and
requirements in a HUGR and validation that extensions are correctly specified.
Experimental feature which allows automatic inference of which extra extensions
are required at runtime by a HUGR when validating it.
Not enabled by default.
- `declarative`:
Experimental support for declaring extensions in YAML files, support is limited.
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/builder/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ impl<B: AsMut<Hugr> + AsRef<Hugr>> CFGBuilder<B> {
signature.input,
vec![type_row![]; n_cases],
signature.output,
signature.extension_reqs,
signature.runtime_reqs,
)
}

Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/builder/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<B: AsMut<Hugr> + AsRef<Hugr>> ConditionalBuilder<B> {
.clone()
.try_into()
.expect("Parent node does not have Conditional optype.");
let extension_delta = cond.signature().extension_reqs.clone();
let extension_delta = cond.signature().runtime_reqs.clone();
let inputs = cond
.case_input_row(case)
.ok_or(ConditionalBuildError::NotCase { conditional, case })?;
Expand Down
8 changes: 4 additions & 4 deletions hugr-core/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ impl<'a> Context<'a> {
}

OpType::DFG(dfg) => {
let extensions = self.export_ext_set(&dfg.signature.extension_reqs);
let extensions = self.export_ext_set(&dfg.signature.runtime_reqs);
regions = self
.bump
.alloc_slice_copy(&[self.export_dfg(node, extensions)]);
Expand Down Expand Up @@ -255,7 +255,7 @@ impl<'a> Context<'a> {
constraints,
signature,
});
let extensions = this.export_ext_set(&func.signature.body().extension_reqs);
let extensions = this.export_ext_set(&func.signature.body().runtime_reqs);
regions = this
.bump
.alloc_slice_copy(&[this.export_dfg(node, extensions)]);
Expand Down Expand Up @@ -659,7 +659,7 @@ impl<'a> Context<'a> {
panic!("expected a `Case` node as a child of a `Conditional` node");
};

let extensions = self.export_ext_set(&case_op.signature.extension_reqs);
let extensions = self.export_ext_set(&case_op.signature.runtime_reqs);
regions.push(self.export_dfg(child, extensions));
}

Expand Down Expand Up @@ -723,7 +723,7 @@ impl<'a> Context<'a> {
pub fn export_func_type<RV: MaybeRV>(&mut self, t: &FuncTypeBase<RV>) -> model::TermId {
let inputs = self.export_type_row(t.input());
let outputs = self.export_type_row(t.output());
let extensions = self.export_ext_set(&t.extension_reqs);
let extensions = self.export_ext_set(&t.runtime_reqs);
self.make_term(model::Term::FuncType {
inputs,
outputs,
Expand Down
17 changes: 7 additions & 10 deletions hugr-core/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,11 +483,8 @@ pub struct Extension {
pub version: Version,
/// Unique identifier for the extension.
pub name: ExtensionId,
/// Other extensions defining types used by this extension.
/// That is, an upper-bound on the types that can be returned by
/// computing the signature of any operation in this extension,
/// for any possible [TypeArg].
pub extension_reqs: ExtensionSet,
/// Runtime dependencies this extension has on other extensions.
pub runtime_reqs: ExtensionSet,
/// Types defined by this extension.
types: BTreeMap<TypeName, TypeDef>,
/// Static values defined by this extension.
Expand All @@ -513,7 +510,7 @@ impl Extension {
Self {
name,
version,
extension_reqs: Default::default(),
runtime_reqs: Default::default(),
types: Default::default(),
values: Default::default(),
operations: Default::default(),
Expand Down Expand Up @@ -571,10 +568,10 @@ impl Extension {
}
}

/// Extend the requirements of this extension with another set of extensions.
pub fn add_requirements(&mut self, extension_reqs: impl Into<ExtensionSet>) {
let reqs = mem::take(&mut self.extension_reqs);
self.extension_reqs = reqs.union(extension_reqs.into());
/// Extend the runtime requirements of this extension with another set of extensions.
pub fn add_requirements(&mut self, runtime_reqs: impl Into<ExtensionSet>) {
let reqs = mem::take(&mut self.runtime_reqs);
self.runtime_reqs = reqs.union(runtime_reqs.into());
}

/// Allows read-only access to the operations in this Extension
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/extension/declarative/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl SignatureDeclaration {
let body = FuncValueType {
input: make_type_row(&self.inputs)?,
output: make_type_row(&self.outputs)?,
extension_reqs: self.extensions.clone(),
runtime_reqs: self.extensions.clone(),
};

let poly_func = PolyFuncTypeRV::new(op_params, body);
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/extension/op_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl SignatureFunc {
SignatureFunc::MissingValidateFunc(ts) => (ts, args),
};
let mut res = pf.instantiate(args, exts)?;
res.extension_reqs.insert(def.extension.clone());
res.runtime_reqs.insert(def.extension.clone());

// If there are any row variables left, this will fail with an error:
res.try_into()
Expand Down
5 changes: 1 addition & 4 deletions hugr-core/src/extension/resolution/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,8 @@ pub(crate) fn collect_signature_exts<RV: MaybeRV>(
used_extensions: &mut ExtensionRegistry,
missing_extensions: &mut ExtensionSet,
) {
// Note that we do not include the signature's `extension_reqs` here, as those refer
// Note that we do not include the signature's `runtime_reqs` here, as those refer
// to _runtime_ requirements that we do not be require to be defined.
//
// See https://github.com/CQCL/hugr/issues/1734
// TODO: Update comment once that issue gets implemented.
collect_type_row_exts(&signature.input, used_extensions, missing_extensions);
collect_type_row_exts(&signature.output, used_extensions, missing_extensions);
}
Expand Down
4 changes: 1 addition & 3 deletions hugr-core/src/extension/resolution/types_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,8 @@ fn resolve_signature_exts(
extensions: &ExtensionRegistry,
used_extensions: &mut ExtensionRegistry,
) -> Result<(), ExtensionResolutionError> {
// Note that we do not include the signature's `extension_reqs` here, as those refer
// Note that we do not include the signature's `runtime_reqs` here, as those refer
// to _runtime_ requirements that may not be currently present.
// See https://github.com/CQCL/hugr/issues/1734
// TODO: Update comment once that issue gets implemented.
resolve_type_row_exts(node, &mut signature.input, extensions, used_extensions)?;
resolve_type_row_exts(node, &mut signature.output, extensions, used_extensions)?;
Ok(())
Expand Down
6 changes: 3 additions & 3 deletions hugr-core/src/hugr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ impl Hugr {
pub fn infer_extensions(&mut self, remove: bool) -> Result<(), ExtensionError> {
fn delta_mut(optype: &mut OpType) -> Option<&mut ExtensionSet> {
match optype {
OpType::DFG(dfg) => Some(&mut dfg.signature.extension_reqs),
OpType::DFG(dfg) => Some(&mut dfg.signature.runtime_reqs),
OpType::DataflowBlock(dfb) => Some(&mut dfb.extension_delta),
OpType::TailLoop(tl) => Some(&mut tl.extension_delta),
OpType::CFG(cfg) => Some(&mut cfg.signature.extension_reqs),
OpType::CFG(cfg) => Some(&mut cfg.signature.runtime_reqs),
OpType::Conditional(c) => Some(&mut c.extension_delta),
OpType::Case(c) => Some(&mut c.signature.extension_reqs),
OpType::Case(c) => Some(&mut c.signature.runtime_reqs),
//OpType::Lift(_) // Not ATM: only a single element, and we expect Lift to be removed
//OpType::FuncDefn(_) // Not at present due to the possibility of recursion
_ => None,
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/hugr/rewrite/outline_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl OutlineCfg {
}
}
}
extension_delta = extension_delta.union(o.signature().extension_reqs.clone());
extension_delta = extension_delta.union(o.signature().runtime_reqs.clone());
let external_succs = h.output_neighbours(n).filter(|s| !self.blocks.contains(s));
match external_succs.at_most_one() {
Ok(None) => (), // No external successors
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/hugr/rewrite/replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ mod test {
},
op_sig.input()
);
h.simple_entry_builder_exts(op_sig.output.clone(), 1, op_sig.extension_reqs.clone())?
h.simple_entry_builder_exts(op_sig.output.clone(), 1, op_sig.runtime_reqs.clone())?
} else {
h.simple_block_builder(op_sig.into_owned(), 1)?
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"size": 2
}
],
"extension_reqs": []
"runtime_reqs": []
}
},
{
Expand Down Expand Up @@ -81,7 +81,7 @@
"size": 2
}
],
"extension_reqs": [
"runtime_reqs": [
"logic"
]
}
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/hugr/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl Hugr {
return Err(ValidationError::ExtensionsNotInferred { node: parent });
}
let parent_extensions = match parent_op.inner_function_type() {
Some(s) => s.extension_reqs.clone(),
Some(s) => s.runtime_reqs.clone(),
None => match parent_op.tag() {
OpTag::Cfg | OpTag::Conditional => parent_op.extension_delta(),
// ModuleRoot holds but does not execute its children, so allow any extensions
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/ops/controlflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ impl OpTrait for Case {
}

fn extension_delta(&self) -> ExtensionSet {
self.signature.extension_reqs.clone()
self.signature.runtime_reqs.clone()
}

fn tag(&self) -> OpTag {
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/ops/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl<T: DataflowOpTrait + Clone> OpTrait for T {
Some(DataflowOpTrait::signature(self))
}
fn extension_delta(&self) -> ExtensionSet {
DataflowOpTrait::signature(self).extension_reqs.clone()
DataflowOpTrait::signature(self).runtime_reqs.clone()
}
fn other_input(&self) -> Option<EdgeKind> {
DataflowOpTrait::other_input(self)
Expand Down
24 changes: 12 additions & 12 deletions hugr-core/src/types/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ pub struct FuncTypeBase<ROWVARS: MaybeRV> {
/// Value outputs of the function.
#[cfg_attr(test, proptest(strategy = "any_with::<TypeRowBase<ROWVARS>>(params)"))]
pub output: TypeRowBase<ROWVARS>,
/// The extension requirements which are added by the operation
pub extension_reqs: ExtensionSet,
/// The extensions the function specifies as required at runtime.
pub runtime_reqs: ExtensionSet,
}

/// The concept of "signature" in the spec - the edges required to/from a node
Expand All @@ -51,9 +51,9 @@ pub type Signature = FuncTypeBase<NoRV>;
pub type FuncValueType = FuncTypeBase<RowVariable>;

impl<RV: MaybeRV> FuncTypeBase<RV> {
/// Builder method, add extension_reqs to a FunctionType
/// Builder method, add runtime_reqs to a FunctionType
pub fn with_extension_delta(mut self, rs: impl Into<ExtensionSet>) -> Self {
self.extension_reqs = self.extension_reqs.union(rs.into());
self.runtime_reqs = self.runtime_reqs.union(rs.into());
self
}

Expand All @@ -66,7 +66,7 @@ impl<RV: MaybeRV> FuncTypeBase<RV> {
Self {
input: self.input.substitute(tr),
output: self.output.substitute(tr),
extension_reqs: self.extension_reqs.substitute(tr),
runtime_reqs: self.runtime_reqs.substitute(tr),
}
}

Expand All @@ -75,7 +75,7 @@ impl<RV: MaybeRV> FuncTypeBase<RV> {
Self {
input: input.into(),
output: output.into(),
extension_reqs: ExtensionSet::new(),
runtime_reqs: ExtensionSet::new(),
}
}

Expand Down Expand Up @@ -118,7 +118,7 @@ impl<RV: MaybeRV> FuncTypeBase<RV> {
) -> Result<(), SignatureError> {
self.input.validate(extension_registry, var_decls)?;
self.output.validate(extension_registry, var_decls)?;
self.extension_reqs.validate(var_decls)
self.runtime_reqs.validate(var_decls)
}

/// Returns a registry with the concrete extensions used by this signature.
Expand Down Expand Up @@ -160,7 +160,7 @@ impl<RV: MaybeRV> Default for FuncTypeBase<RV> {
Self {
input: Default::default(),
output: Default::default(),
extension_reqs: Default::default(),
runtime_reqs: Default::default(),
}
}
}
Expand Down Expand Up @@ -286,7 +286,7 @@ impl<RV: MaybeRV> Display for FuncTypeBase<RV> {
f.write_str(" -> ")?;
}
f.write_char('[')?;
self.extension_reqs.fmt(f)?;
self.runtime_reqs.fmt(f)?;
f.write_char(']')?;
self.output.fmt(f)
}
Expand All @@ -298,7 +298,7 @@ impl TryFrom<FuncValueType> for Signature {
fn try_from(value: FuncValueType) -> Result<Self, Self::Error> {
let input: TypeRow = value.input.try_into()?;
let output: TypeRow = value.output.try_into()?;
Ok(Self::new(input, output).with_extension_delta(value.extension_reqs))
Ok(Self::new(input, output).with_extension_delta(value.runtime_reqs))
}
}

Expand All @@ -307,7 +307,7 @@ impl From<Signature> for FuncValueType {
Self {
input: value.input.into(),
output: value.output.into(),
extension_reqs: value.extension_reqs,
runtime_reqs: value.runtime_reqs,
}
}
}
Expand All @@ -316,7 +316,7 @@ impl<RV1: MaybeRV, RV2: MaybeRV> PartialEq<FuncTypeBase<RV1>> for FuncTypeBase<R
fn eq(&self, other: &FuncTypeBase<RV1>) -> bool {
self.input == other.input
&& self.output == other.output
&& self.extension_reqs == other.extension_reqs
&& self.runtime_reqs == other.runtime_reqs
}
}

Expand Down
4 changes: 2 additions & 2 deletions hugr-passes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ Please read the [API documentation here][].
## Experimental Features

- `extension_inference`:
Experimental feature which allows automatic inference of extension usages and
requirements in a HUGR and validation that extensions are correctly specified.
Experimental feature which allows automatic inference of which extra extensions
are required at runtime by a HUGR when validating it.
Not enabled by default.

## Recent Changes
Expand Down
6 changes: 3 additions & 3 deletions hugr-py/src/hugr/_serialization/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class OpDef(ConfiguredBaseModel, populate_by_name=True):

def deserialize(self, extension: ext.Extension) -> ext.OpDef:
signature = ext.OpDefSig(
self.signature.deserialize().with_extension_reqs([extension.name])
self.signature.deserialize().with_runtime_reqs([extension.name])
if self.signature
else None,
self.binary,
Expand All @@ -122,7 +122,7 @@ def deserialize(self, extension: ext.Extension) -> ext.OpDef:
class Extension(ConfiguredBaseModel):
version: SemanticVersion
name: ExtensionId
extension_reqs: set[ExtensionId]
runtime_reqs: set[ExtensionId]
types: dict[str, TypeDef]
values: dict[str, ExtensionValue]
operations: dict[str, OpDef]
Expand All @@ -135,7 +135,7 @@ def deserialize(self) -> ext.Extension:
e = ext.Extension(
version=self.version, # type: ignore[arg-type]
name=self.name,
extension_reqs=self.extension_reqs,
runtime_reqs=self.runtime_reqs,
)

for k, t in self.types.items():
Expand Down
8 changes: 4 additions & 4 deletions hugr-py/src/hugr/_serialization/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,12 @@ class DFG(DataflowOp):

def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None:
self.signature = FunctionType(
input=list(inputs), output=list(outputs), extension_reqs=ExtensionSet([])
input=list(inputs), output=list(outputs), runtime_reqs=ExtensionSet([])
)

def deserialize(self) -> ops.DFG:
sig = self.signature.deserialize()
return ops.DFG(sig.input, sig.output, sig.extension_reqs)
return ops.DFG(sig.input, sig.output, sig.runtime_reqs)


# ------------------------------------------------
Expand Down Expand Up @@ -443,7 +443,7 @@ class Case(BaseOp):

def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None:
self.signature = stys.FunctionType(
input=list(inputs), output=list(outputs), extension_reqs=ExtensionSet([])
input=list(inputs), output=list(outputs), runtime_reqs=ExtensionSet([])
)

def deserialize(self) -> ops.Case:
Expand Down Expand Up @@ -484,7 +484,7 @@ class CFG(DataflowOp):

def insert_port_types(self, inputs: TypeRow, outputs: TypeRow) -> None:
self.signature = FunctionType(
input=list(inputs), output=list(outputs), extension_reqs=ExtensionSet([])
input=list(inputs), output=list(outputs), runtime_reqs=ExtensionSet([])
)

def deserialize(self) -> ops.CFG:
Expand Down
Loading

0 comments on commit 5f5bce4

Please sign in to comment.