Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
937cd14
Add TypeTransformer and (Sum/Function)Type(Arg/Row)::transform
acl-cqc Mar 11, 2025
815536b
trait Transformable to common up all the 'let mut any_change = false'…
acl-cqc Mar 12, 2025
cc1e8f2
Transformable v2: implement for [E], works without iter_mut/etc. in a…
acl-cqc Mar 12, 2025
4888184
first test, fix CustomType bound caching
acl-cqc Mar 17, 2025
7002e4d
Second test, fix SumType caching
acl-cqc Mar 17, 2025
6cc7cea
Make clippy happy
acl-cqc Mar 17, 2025
d43784b
Add HugrMut::optype_mut (v2, allow mutating root if RootHandle == Node)
acl-cqc Mar 11, 2025
422c496
WIP add hugr-passes/src/lower_types.rs (w/ change_node, subst_ty)
acl-cqc Mar 5, 2025
76ed391
Add def_arc
acl-cqc Mar 11, 2025
ed5b5dd
change_node, change_type, and the rest
acl-cqc Mar 10, 2025
adcbbf6
Use TypeTransformer framework, removing most type_stuff from lower_ty…
acl-cqc Mar 11, 2025
d84ae4e
Add a load of copy/discard lowering stuff, OpReplacement
acl-cqc Mar 12, 2025
bfa52cf
OpHashWrapper
acl-cqc Mar 12, 2025
b373571
Parametrized type support
acl-cqc Mar 17, 2025
a8e613a
remove copy_discard stuff
acl-cqc Mar 17, 2025
24ed15c
Assume less in OpReplacement::replace
acl-cqc Mar 17, 2025
9153fcf
parametrized ops
acl-cqc Mar 17, 2025
a89879c
Comments, renaming, use const_fn
acl-cqc Mar 17, 2025
c78d88a
Comment const_fn TODO
acl-cqc Mar 17, 2025
bf6a9a4
Test panics on unexpected argument - simpler, better
acl-cqc Mar 18, 2025
5ecd9e6
test functiontype
acl-cqc Mar 18, 2025
d9a6d29
clippy that new test
acl-cqc Mar 18, 2025
83e798e
Merge remote-tracking branch 'origin/main' into acl/type_transform
acl-cqc Mar 18, 2025
84fe82d
WIP setup for test
acl-cqc Mar 18, 2025
6168353
First test
acl-cqc Mar 18, 2025
fcb85a2
read only makes sense for Copyables
acl-cqc Mar 18, 2025
0f9aa17
Extend test to Calls of polyfunc; comments, monomorphize first
acl-cqc Mar 18, 2025
74c6775
no, instantiate the calls with types being lowered
acl-cqc Mar 18, 2025
00fd284
Consts: HashMap keyed by either, add lower_ methods. Test TailLoop an…
acl-cqc Mar 18, 2025
9f02acf
clippy, turn off type-complexity
acl-cqc Mar 18, 2025
a0ac6d6
Actual Error for check_sig, add setter method
acl-cqc Mar 19, 2025
6ac9efc
docs
acl-cqc Mar 19, 2025
044ff32
Test variable, boundednat; use list_type
acl-cqc Mar 19, 2025
b539e2f
Yet Another ValidationLevel interface
acl-cqc Mar 19, 2025
2c7e035
Merge remote-tracking branch 'origin/main' into acl/type_transform
acl-cqc Mar 19, 2025
6b190a6
Merge branch 'acl/type_transform' into acl/lower_types
acl-cqc Mar 19, 2025
bd24d1a
clippy
acl-cqc Mar 19, 2025
a5d8b65
doclinxs
acl-cqc Mar 19, 2025
6b1438c
pub re-export
acl-cqc Mar 19, 2025
d1036bc
fix const_loop for extensions
acl-cqc Mar 19, 2025
d19dc5a
fix other test for extensions, but turn off extension validation afte…
acl-cqc Mar 19, 2025
d0fddde
Add another test of Conditional + Case
acl-cqc Mar 21, 2025
3494887
common up read_op
acl-cqc Mar 21, 2025
ffdcaf2
test tidies
acl-cqc Mar 21, 2025
6f8f43c
No need to validate, run() does it for us
acl-cqc Mar 21, 2025
e3da259
check_sig: use Option::unzip to tuple-ize
acl-cqc Mar 21, 2025
28f2470
Move private utility classes below the pub ones; add comments
acl-cqc Mar 21, 2025
bef90b0
Comments - all callbacks return Option
acl-cqc Mar 24, 2025
85df7ff
test: Rename lower_types to lowerer
acl-cqc Mar 25, 2025
507f027
Extend loop_const test
acl-cqc Mar 25, 2025
bae0ebe
Add copy/dup linearization stuff
acl-cqc Mar 25, 2025
8fa79bd
do_copy_chain => insert_copy_discard
acl-cqc Mar 21, 2025
6a186a5
Move insert_copy_discard into Linearizer
acl-cqc Mar 25, 2025
6d8a89b
Add LinearizeError
acl-cqc Mar 21, 2025
3f0f1e6
pass Linearizer to callbacks
acl-cqc Mar 21, 2025
974a25b
comments
acl-cqc Mar 24, 2025
2bbf663
first test, don't linearize root node outputs, reject nonlocal edges
acl-cqc Mar 21, 2025
290a8ae
copy_fn/discard_fn return Result
acl-cqc Mar 23, 2025
19b1442
linearize takes &TypeDef not TypeDef
acl-cqc Mar 23, 2025
269f0f1
OpReplacement::add(&self, ...) -> add_hugr(self, ...)
acl-cqc Mar 24, 2025
f6a1af5
Drop an else-continue
acl-cqc Mar 25, 2025
ac9adac
Add OpReplacement::add for builder
acl-cqc Mar 24, 2025
65eaf52
Handle Sum Types in copy_op/discard_op
acl-cqc Mar 25, 2025
354a89c
drop redundant allow-missing_docs
acl-cqc Mar 25, 2025
1b31631
Refactor test code, fix --all-features
acl-cqc Mar 23, 2025
d5cbd58
Test copying+discarding an option of two elements
acl-cqc Mar 25, 2025
63bdd3b
tidy imports
acl-cqc Mar 25, 2025
f1f4474
discard_array (untested)
acl-cqc Mar 25, 2025
9d8b32a
add discard_array test
acl-cqc Mar 25, 2025
895d392
Works for monomorphic only as CompoundOp must be so
acl-cqc Mar 25, 2025
4f33cdb
Fix all-features
acl-cqc Mar 25, 2025
71cf3a6
copy_array and test
acl-cqc Mar 25, 2025
987fc0e
export copy_array/discard_array, for now at least
acl-cqc Mar 24, 2025
1ac3728
Combine lower_consts(_parametric) with lower_(parametric_)type
acl-cqc Mar 25, 2025
e768814
Test sig checking
acl-cqc Mar 25, 2025
506570b
No, remove sig checking
acl-cqc Mar 25, 2025
0958e2a
Test funky partial replace
acl-cqc Mar 25, 2025
74cfdb1
common up just_elem_type
acl-cqc Mar 25, 2025
dc79c93
comment spacing
acl-cqc Mar 25, 2025
63d24b0
RIP SignatureMismatch
acl-cqc Mar 25, 2025
ba63fbe
Reinstate separate lower_consts/lower_consts_parametric
acl-cqc Mar 26, 2025
2c7bb80
Remove the boxes
acl-cqc Mar 26, 2025
08d3227
drop comment re. validation_level
acl-cqc Mar 26, 2025
dedc3d5
rename module lower_types -> replace_types
acl-cqc Mar 26, 2025
9993467
rename LowerTypes=>ReplaceTypes, ChangeTypeError => ReplaceTypesError
acl-cqc Mar 26, 2025
cc81d87
rename methods, parametric => parametrized
acl-cqc Mar 26, 2025
74c6492
doc notes
acl-cqc Mar 26, 2025
18316de
comment/doc updates
acl-cqc Mar 26, 2025
520e414
fmt
acl-cqc Mar 26, 2025
0814bf2
callbacks for Const take &ReplaceTypes
acl-cqc Mar 26, 2025
0a82fef
Replace that break 'changed block with a match, + map_or_else to avoi…
acl-cqc Mar 26, 2025
94c0ff3
Add Type::as_extension
acl-cqc Mar 26, 2025
e9ff81c
wip
acl-cqc Mar 26, 2025
cf6451f
add list_const handler, use in test
acl-cqc Mar 26, 2025
9a355d5
Clarify replace_consts_parametrized callback
acl-cqc Mar 26, 2025
ec2d0ba
const callbacks report errors via Result
acl-cqc Mar 26, 2025
c9d7033
fmt+fix
acl-cqc Mar 26, 2025
812ac89
comment tweaks
acl-cqc Mar 26, 2025
ae7bd6e
Merge remote-tracking branch 'origin/main' into acl/lower_types
acl-cqc Mar 26, 2025
e0937ee
docs
acl-cqc Mar 26, 2025
36df03c
and some more - warn on missing_docs except ReplaceTypesError
acl-cqc Mar 26, 2025
71f8c0b
Merge remote-tracking branch 'origin/main' into acl/lower_types
acl-cqc Mar 26, 2025
dc0c7dd
Merge branch 'acl/lower_types' into acl/lower_types_linearize
acl-cqc Mar 26, 2025
31ba4e0
docs, make pub, more errors
acl-cqc Mar 26, 2025
86c73ed
Test copyable element inside Sum - breaks test
acl-cqc Mar 26, 2025
92d7a51
Error on copyable; handle copyable elements of sums - fixes
acl-cqc Mar 26, 2025
582b9f1
register errors with type; panic on function as already ruled out
acl-cqc Mar 26, 2025
95da97d
more docs - no overriding copy/discard of non-extension types
acl-cqc Mar 26, 2025
c7e56e6
pub discard_op
acl-cqc Mar 27, 2025
d4acce0
Merge acl/lower_types_linearize{,_array}, pub array_type_def
acl-cqc Mar 27, 2025
6bd21a5
wip
acl-cqc Mar 27, 2025
6cad884
Move all handlers into handlers.rs
acl-cqc Mar 27, 2025
a1e63de
rm Boxes
acl-cqc Mar 28, 2025
654170f
Merge branch 'acl/lower_types_linearize' into acl/lower_types_lineari…
acl-cqc Mar 28, 2025
2afd2e6
remove boxes
acl-cqc Mar 28, 2025
7634e92
Only allow copy/discard funcs for *Custom*Type's
acl-cqc Mar 28, 2025
0cd31e0
single callback taking num_outports != 1
acl-cqc Mar 28, 2025
65b8993
In insert_copy_discard, a discard really is a 0-way copy
acl-cqc Mar 28, 2025
198f990
renaming
acl-cqc Mar 28, 2025
517cd0d
Generalize test 2,3,4 copies
acl-cqc Mar 28, 2025
4ccbd0c
Merge branch 'acl/lower_types_linearize' into acl/lower_types_lineari…
acl-cqc Mar 28, 2025
4416616
comment about issue
acl-cqc Mar 28, 2025
272f024
Simplify test w/binary copy to just option type, add more complex w/ …
acl-cqc Mar 28, 2025
e74b12b
combine the two test extensions
acl-cqc Mar 28, 2025
34bd90d
tweaks
acl-cqc Mar 28, 2025
cf09fc9
Merge branch 'acl/lower_types_linearize' into acl/lower_types_lineari…
acl-cqc Mar 28, 2025
a2cba09
filter
acl-cqc Mar 28, 2025
3084004
so that
acl-cqc Mar 28, 2025
cec9162
insert_copy_discard takes Wire, no Type
acl-cqc Mar 28, 2025
bf74996
Rename OpReplacement -> NodeTemplate
acl-cqc Mar 28, 2025
221bf7d
fix dataflowparent doclink
acl-cqc Mar 28, 2025
f6312bc
Remove linearize() proxy methods, add linearizer() getter - docs a mess
acl-cqc Mar 30, 2025
5fe25c0
docs+notes
acl-cqc Mar 30, 2025
edd2126
fix lists in docs
acl-cqc Mar 30, 2025
5ea9763
Add Linearizer trait, rename to DelegatingLinearizer
acl-cqc Mar 31, 2025
cc4fd68
Pass &dyn Linearizer - requires making object-safe
acl-cqc Mar 31, 2025
8a1ff0c
No - revert - instead pass ref to new CallbackHandler struct
acl-cqc Mar 31, 2025
d5e4ac3
Add LinearizeError::WrongSignature
acl-cqc Apr 1, 2025
b259426
Remove NeedDiscard, rename NeedCopy
acl-cqc Apr 1, 2025
a14fafa
test, also check sig for register(CustTy, NodeTempl*2)
acl-cqc Apr 1, 2025
a4686d3
lint
doug-q Apr 2, 2025
1abf1b4
docs
doug-q Apr 2, 2025
7e3efcc
Rename register(=>_simple,_parametric=>_callback), docs
acl-cqc Apr 2, 2025
753d152
Merge commit '9ad9e6d3a0c7fd576ca4296bf35aeaa6db732220' into acl/lowe…
acl-cqc Apr 8, 2025
9678b51
Merge branch 'acl/lower_types_linearize' into acl/lower_types_lineari…
acl-cqc Apr 8, 2025
4823c95
Early return for discard; generalize to n-way copy (oops); comments
acl-cqc Apr 8, 2025
8e9740a
Generalise test to >2 outports, fix impl
acl-cqc Apr 8, 2025
318c7fc
fix docs
acl-cqc Apr 9, 2025
f5de2ec
Fix list_const, add array_const
acl-cqc Apr 15, 2025
6ae093a
test, add ReplaceTypesError::ConstError
acl-cqc Apr 15, 2025
ff1772f
Default includes handlers, new_empty does not
acl-cqc Apr 15, 2025
63dc9a1
docs
acl-cqc Apr 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion hugr-core/src/std_extensions/collections/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ lazy_static! {
};
}

fn array_type_def() -> &'static TypeDef {
/// Gets the [TypeDef] for arrays. Note that instantiations are more easily
/// created via [array_type] and [array_type_parametric]
pub fn array_type_def() -> &'static TypeDef {
EXTENSION.get_type(&ARRAY_TYPENAME).unwrap()
}

Expand Down
111 changes: 74 additions & 37 deletions hugr-passes/src/replace_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;

use handlers::list_const;
use hugr_core::std_extensions::collections::array::array_type_def;
use hugr_core::std_extensions::collections::list::list_type_def;
use thiserror::Error;

use hugr_core::builder::{BuildError, BuildHandle, Dataflow};
Expand All @@ -19,7 +22,7 @@ use hugr_core::ops::{
Value, CFG, DFG,
};
use hugr_core::types::{
CustomType, Signature, Transformable, Type, TypeArg, TypeEnum, TypeTransformer,
ConstTypeError, CustomType, Signature, Transformable, Type, TypeArg, TypeEnum, TypeTransformer,
};
use hugr_core::{Hugr, HugrView, Node, Wire};

Expand Down Expand Up @@ -125,7 +128,7 @@ impl NodeTemplate {
/// * See also limitations noted for [Linearizer].
///
/// [monomorphization]: super::monomorphize()
#[derive(Clone, Default)]
#[derive(Clone)]
pub struct ReplaceTypes {
type_map: HashMap<CustomType, Type>,
param_types: HashMap<ParametricType, Arc<dyn Fn(&[TypeArg]) -> Option<Type>>>,
Expand All @@ -143,6 +146,16 @@ pub struct ReplaceTypes {
validation: ValidationLevel,
}

impl Default for ReplaceTypes {
fn default() -> Self {
let mut res = Self::new_empty();
res.linearize = DelegatingLinearizer::default();
res.replace_consts_parametrized(array_type_def(), handlers::array_const);
res.replace_consts_parametrized(list_type_def(), list_const);
res
}
}

impl TypeTransformer for ReplaceTypes {
type Err = ReplaceTypesError;

Expand Down Expand Up @@ -173,10 +186,27 @@ pub enum ReplaceTypesError {
#[error(transparent)]
ValidationError(#[from] ValidatePassError),
#[error(transparent)]
ConstError(#[from] ConstTypeError),
#[error(transparent)]
LinearizeError(#[from] LinearizeError),
}

impl ReplaceTypes {
/// Makes a new instance. Unlike [Self::default], this does not understand
/// any extension types, even those in the prelude.
pub fn new_empty() -> Self {
Self {
type_map: Default::default(),
param_types: Default::default(),
linearize: DelegatingLinearizer::new_empty(),
op_map: Default::default(),
param_ops: Default::default(),
consts: Default::default(),
param_consts: Default::default(),
validation: Default::default(),
}
}

/// Sets the validation level used before and after the pass is run.
pub fn validation_level(mut self, level: ValidationLevel) -> Self {
self.validation = level;
Expand Down Expand Up @@ -447,38 +477,7 @@ impl ReplaceTypes {
}
}

pub mod handlers {
//! Callbacks for use with [ReplaceTypes::replace_consts_parametrized]
use hugr_core::ops::{constant::OpaqueValue, Value};
use hugr_core::std_extensions::collections::list::ListValue;
use hugr_core::types::Transformable;

use super::{ReplaceTypes, ReplaceTypesError};

/// Handler for [ListValue] constants that recursively [ReplaceTypes::change_value]s
/// the elements of the list
pub fn list_const(
val: &OpaqueValue,
repl: &ReplaceTypes,
) -> Result<Option<Value>, ReplaceTypesError> {
let Some(lv) = val.value().downcast_ref::<ListValue>() else {
return Ok(None);
};
let mut vals: Vec<Value> = lv.get_contents().to_vec();
let mut ch = false;
for v in vals.iter_mut() {
ch |= repl.change_value(v)?;
}
// If none of the values has changed, assume the Type hasn't (Values have a single known type)
if !ch {
return Ok(None);
};

let mut elem_t = lv.get_element_type().clone();
elem_t.transform(repl)?;
Ok(Some(ListValue::new(elem_t, vals).into()))
}
}
pub mod handlers;

#[derive(Clone, Hash, PartialEq, Eq)]
struct OpHashWrapper {
Expand Down Expand Up @@ -536,20 +535,26 @@ mod test {
use hugr_core::extension::simple_op::MakeExtensionOp;
use hugr_core::extension::{TypeDefBound, Version};

use hugr_core::ops::constant::OpaqueValue;
use hugr_core::ops::{ExtensionOp, NamedOp, OpTrait, OpType, Tag, Value};
use hugr_core::std_extensions::arithmetic::int_types::ConstInt;
use hugr_core::std_extensions::arithmetic::{conversions::ConvertOpDef, int_types::INT_TYPES};
use hugr_core::std_extensions::collections::array::{
array_type, ArrayOp, ArrayOpDef, ArrayValue,
array_type, array_type_def, ArrayOp, ArrayOpDef, ArrayValue,
};
use hugr_core::std_extensions::collections::list::{
list_type, list_type_def, ListOp, ListValue,
};

use hugr_core::hugr::ValidationError;
use hugr_core::types::{PolyFuncType, Signature, SumType, Type, TypeArg, TypeBound, TypeRow};
use hugr_core::{hugr::IdentList, type_row, Extension, HugrView};
use itertools::Itertools;
use rstest::rstest;

use crate::validation::ValidatePassError;

use super::ReplaceTypesError;
use super::{handlers::list_const, NodeTemplate, ReplaceTypes};

const PACKED_VEC: &str = "PackedVec";
Expand Down Expand Up @@ -792,8 +797,6 @@ mod test {
let backup = tl.finish_hugr().unwrap();

let mut lowerer = ReplaceTypes::default();
// Recursively descend into lists
lowerer.replace_consts_parametrized(list_type_def(), list_const);

// 1. Lower List<T> to Array<10, T> UNLESS T is usize_t() or i64_t
lowerer.replace_parametrized_type(list_type_def(), |args| {
Expand Down Expand Up @@ -951,4 +954,38 @@ mod test {
["NoBoundsCheck.read", "collections.list.get"]
);
}

#[rstest]
#[case(&[])]
#[case(&[3])]
#[case(&[5,7,11,13,17,19])]
fn array_const(#[case] vals: &[u64]) {
use super::handlers::array_const;
let mut dfb = DFGBuilder::new(inout_sig(
type_row![],
array_type(vals.len() as _, usize_t()),
))
.unwrap();
let c = dfb.add_load_value(ArrayValue::new(
usize_t(),
vals.iter().map(|u| ConstUsize::new(*u).into()),
));
let backup = dfb.finish_hugr_with_outputs([c]).unwrap();

let mut repl = ReplaceTypes::new_empty();
let usize_custom_t = usize_t().as_extension().unwrap().clone();
repl.replace_type(usize_custom_t.clone(), INT_TYPES[6].clone());
repl.replace_consts(usize_custom_t, |cst: &OpaqueValue, _| {
let cu = cst.value().downcast_ref::<ConstUsize>().unwrap();
Ok(ConstInt::new_u(6, cu.value())?.into())
});
assert!(
matches!(repl.run(&mut backup.clone()), Err(ReplaceTypesError::ValidationError(ValidatePassError::OutputError {
err: ValidationError::IncompatiblePorts {from, to, ..}, ..
})) if backup.get_optype(from).is_const() && to == c.node())
);
repl.replace_consts_parametrized(array_type_def(), array_const);
let mut h = backup;
repl.run(&mut h).unwrap(); // Includes validation
}
}
Loading
Loading