From 58c66ee4bd44a7fbc8955bf8f658afc9804b5d6e Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Mon, 27 Nov 2023 18:28:56 +0000 Subject: [PATCH 1/6] refactor: use `MakeOpDef` for int_ops --- src/std_extensions/arithmetic/conversions.rs | 9 +- src/std_extensions/arithmetic/int_ops.rs | 572 +++++++------------ src/std_extensions/arithmetic/int_types.rs | 2 +- 3 files changed, 195 insertions(+), 388 deletions(-) diff --git a/src/std_extensions/arithmetic/conversions.rs b/src/std_extensions/arithmetic/conversions.rs index 56b636f19..4ae262b77 100644 --- a/src/std_extensions/arithmetic/conversions.rs +++ b/src/std_extensions/arithmetic/conversions.rs @@ -7,7 +7,7 @@ use crate::{ Extension, }; -use super::int_types::int_type_var; +use super::int_types::int_tv; use super::{float_types::FLOAT64_TYPE, int_types::LOG_WIDTH_TYPE_PARAM}; /// The extension identifier. @@ -17,15 +17,12 @@ pub const EXTENSION_ID: ExtensionId = ExtensionId::new_unchecked("arithmetic.con pub fn extension() -> Extension { let ftoi_sig = PolyFuncType::new( vec![LOG_WIDTH_TYPE_PARAM], - FunctionType::new( - type_row![FLOAT64_TYPE], - vec![sum_with_error(int_type_var(0))], - ), + FunctionType::new(type_row![FLOAT64_TYPE], vec![sum_with_error(int_tv(0))]), ); let itof_sig = PolyFuncType::new( vec![LOG_WIDTH_TYPE_PARAM], - FunctionType::new(vec![int_type_var(0)], type_row![FLOAT64_TYPE]), + FunctionType::new(vec![int_tv(0)], type_row![FLOAT64_TYPE]), ); let mut extension = Extension::new_with_reqs( diff --git a/src/std_extensions/arithmetic/int_ops.rs b/src/std_extensions/arithmetic/int_ops.rs index cd9221deb..008c5d988 100644 --- a/src/std_extensions/arithmetic/int_ops.rs +++ b/src/std_extensions/arithmetic/int_ops.rs @@ -1,8 +1,9 @@ //! Basic integer operations. -use super::int_types::{get_log_width, int_type_var, LOG_WIDTH_TYPE_PARAM}; +use super::int_types::{get_log_width, int_tv, LOG_WIDTH_TYPE_PARAM}; use crate::extension::prelude::{sum_with_error, BOOL_T}; -use crate::extension::{CustomValidator, ValidateJustArgs}; +use crate::extension::simple_op::MakeOpDef; +use crate::extension::{CustomValidator, OpDef, SignatureFunc, ValidateJustArgs}; use crate::type_row; use crate::types::{FunctionType, PolyFuncType}; use crate::utils::collect_array; @@ -13,6 +14,7 @@ use crate::{ }; use lazy_static::lazy_static; +use strum_macros::{EnumIter, EnumString, IntoStaticStr}; /// The extension identifier. pub const EXTENSION_ID: ExtensionId = ExtensionId::new_unchecked("arithmetic.int"); @@ -34,7 +36,181 @@ impl ValidateJustArgs for IOValidator { Ok(()) } } +/// Logic extension operation definitions. +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, EnumIter, IntoStaticStr, EnumString)] +#[allow(missing_docs, non_camel_case_types)] +pub enum IntOps { + iwiden_u, + iwiden_s, + inarrow_u, + inarrow_s, + itobool, + ifrombool, + ieq, + ine, + ilt_u, + ilt_s, + igt_u, + igt_s, + ile_u, + ile_s, + ige_u, + ige_s, + imax_u, + imax_s, + imin_u, + imin_s, + iadd, + isub, + ineg, + imul, + idivmod_checked_u, + idivmod_u, + idivmod_checked_s, + idivmod_s, + idiv_checked_u, + idiv_u, + imod_checked_u, + imod_u, + idiv_checked_s, + idiv_s, + imod_checked_s, + imod_s, + iabs, + iand, + ior, + ixor, + inot, + ishl, + ishr, + irotl, + irotr, +} + +impl MakeOpDef for IntOps { + fn from_def(op_def: &OpDef) -> Result { + crate::extension::simple_op::try_from_name(op_def.name()) + } + + fn signature(&self) -> SignatureFunc { + use IntOps::*; + match self { + iwiden_s | iwiden_u => CustomValidator::new_with_validator( + int_polytype(2, vec![int_tv(0)], vec![int_tv(1)]), + IOValidator { f_gt_s: false }, + ) + .into(), + inarrow_s | inarrow_u => CustomValidator::new_with_validator( + int_polytype(2, vec![int_tv(0)], vec![sum_with_error(int_tv(1))]), + IOValidator { f_gt_s: true }, + ) + .into(), + itobool => int_polytype(1, vec![int_tv(0)], type_row![BOOL_T]).into(), + ifrombool => int_polytype(1, type_row![BOOL_T], vec![int_tv(0)]).into(), + ieq | ine | ilt_u | ilt_s | igt_u | igt_s | ile_u | ile_s | ige_u | ige_s => { + int_polytype(1, vec![int_tv(0); 2], type_row![BOOL_T]).into() + } + imax_u | imax_s | imin_u | imin_s | iadd | isub | imul | iand | ior | ixor => { + ibinop_sig().into() + } + ineg | iabs | inot => iunop_sig().into(), + //TODO inline + idivmod_checked_u | idivmod_checked_s => { + let intpair: TypeRow = vec![int_tv(0), int_tv(1)].into(); + int_polytype( + 2, + intpair.clone(), + vec![sum_with_error(Type::new_tuple(intpair))], + ) + } + .into(), + idivmod_u | idivmod_s => { + let intpair: TypeRow = vec![int_tv(0), int_tv(1)].into(); + int_polytype(2, intpair.clone(), vec![Type::new_tuple(intpair)]) + } + .into(), + idiv_u | idiv_s => int_polytype(2, vec![int_tv(0), int_tv(1)], vec![int_tv(0)]).into(), + idiv_checked_u | idiv_checked_s => int_polytype( + 2, + vec![int_tv(0), int_tv(1)], + vec![sum_with_error(int_tv(0))], + ) + .into(), + imod_checked_u | imod_checked_s => int_polytype( + 2, + vec![int_tv(0), int_tv(1).clone()], + vec![sum_with_error(int_tv(1))], + ) + .into(), + imod_u | imod_s => { + int_polytype(2, vec![int_tv(0), int_tv(1).clone()], vec![int_tv(1)]).into() + } + ishl | ishr | irotl | irotr => { + int_polytype(2, vec![int_tv(0), int_tv(1)], vec![int_tv(0)]).into() + } + } + } + fn description(&self) -> String { + use IntOps::*; + + match self { + iwiden_u => "widen an unsigned integer to a wider one with the same value", + iwiden_s => "widen a signed integer to a wider one with the same value", + inarrow_u => "narrow an unsigned integer to a narrower one with the same value if possible", + inarrow_s => "narrow a signed integer to a narrower one with the same value if possible", + itobool => "convert to bool (1 is true, 0 is false)", + ifrombool => "convert from bool (1 is true, 0 is false)", + ieq => "equality test", + ine => "inequality test", + ilt_u => "\"less than\" as unsigned integers", + ilt_s => "\"less than\" as signed integers", + igt_u =>"\"greater than\" as unsigned integers", + igt_s => "\"greater than\" as signed integers", + ile_u => "\"less than or equal\" as unsigned integers", + ile_s => "\"less than or equal\" as signed integers", + ige_u => "\"greater than or equal\" as unsigned integers", + ige_s => "\"greater than or equal\" as signed integers", + imax_u => "maximum of unsigned integers", + imax_s => "maximum of signed integers", + imin_u => "minimum of unsigned integers", + imin_s => "minimum of signed integers", + iadd => "addition modulo 2^N (signed and unsigned versions are the same op)", + isub => "subtraction modulo 2^N (signed and unsigned versions are the same op)", + ineg => "negation modulo 2^N (signed and unsigned versions are the same op)", + imul => "multiplication modulo 2^N (signed and unsigned versions are the same op)", + idivmod_checked_u => "given unsigned integers 0 <= n < 2^N, 0 <= m < 2^M, generates unsigned q, r where \ + q*m+r=n, 0<=r "given unsigned integers 0 <= n < 2^N, 0 <= m < 2^M, generates unsigned q, r where \ + q*m+r=n, 0<=r "given signed integer -2^{N-1} <= n < 2^{N-1} and unsigned 0 <= m < 2^M, generates \ + signed q and unsigned r where q*m+r=n, 0<=r "given signed integer -2^{N-1} <= n < 2^{N-1} and unsigned 0 <= m < 2^M, generates \ + signed q and unsigned r where q*m+r=n, 0<=r "as idivmod_checked_u but discarding the second output", + idiv_u => "as idivmod_u but discarding the second output", + imod_checked_u => "as idivmod_checked_u but discarding the first output", + imod_u => "as idivmod_u but discarding the first output", + idiv_checked_s => "as idivmod_checked_s but discarding the second output", + idiv_s => "as idivmod_s but discarding the second output", + imod_checked_s => "as idivmod_checked_s but discarding the first output", + imod_s => "as idivmod_s but discarding the first output", + iabs => "convert signed to unsigned by taking absolute value", + iand => "bitwise AND", + ior => "bitwise OR", + ixor => "bitwise XOR", + inot => "bitwise NOT", + ishl => "shift first input left by k bits where k is unsigned interpretation of second input \ + (leftmost bits dropped, rightmost bits set to zero", + ishr => "shift first input right by k bits where k is unsigned interpretation of second input \ + (rightmost bits dropped, leftmost bits set to zero)", + irotl => "rotate first input left by k bits where k is unsigned interpretation of second input \ + (leftmost bits replace rightmost bits)", + irotr => "rotate first input right by k bits where k is unsigned interpretation of second input \ + (rightmost bits replace leftmost bits)", + }.into() + } +} fn int_polytype( n_vars: usize, input: impl Into, @@ -47,395 +223,28 @@ fn int_polytype( } fn ibinop_sig() -> PolyFuncType { - let int_type_var = int_type_var(0); + let int_type_var = int_tv(0); int_polytype(1, vec![int_type_var.clone(); 2], vec![int_type_var]) } fn iunop_sig() -> PolyFuncType { - let int_type_var = int_type_var(0); + let int_type_var = int_tv(0); int_polytype(1, vec![int_type_var.clone()], vec![int_type_var]) } -fn idivmod_checked_sig() -> PolyFuncType { - let intpair: TypeRow = vec![int_type_var(0), int_type_var(1)].into(); - int_polytype( - 2, - intpair.clone(), - vec![sum_with_error(Type::new_tuple(intpair))], - ) -} - -fn idivmod_sig() -> PolyFuncType { - let intpair: TypeRow = vec![int_type_var(0), int_type_var(1)].into(); - int_polytype(2, intpair.clone(), vec![Type::new_tuple(intpair)]) -} - -/// Extension for basic integer operations. -fn extension() -> Extension { - let itob_sig = int_polytype(1, vec![int_type_var(0)], type_row![BOOL_T]); - - let btoi_sig = int_polytype(1, type_row![BOOL_T], vec![int_type_var(0)]); - - let icmp_sig = int_polytype(1, vec![int_type_var(0); 2], type_row![BOOL_T]); - - let idiv_checked_sig = int_polytype( - 2, - vec![int_type_var(0), int_type_var(1)], - vec![sum_with_error(int_type_var(0))], - ); - - let idiv_sig = int_polytype( - 2, - vec![int_type_var(0), int_type_var(1)], - vec![int_type_var(0)], - ); - - let imod_checked_sig = int_polytype( - 2, - vec![int_type_var(0), int_type_var(1).clone()], - vec![sum_with_error(int_type_var(1))], - ); - - let imod_sig = int_polytype( - 2, - vec![int_type_var(0), int_type_var(1).clone()], - vec![int_type_var(1)], - ); - - let ish_sig = int_polytype( - 2, - vec![int_type_var(0), int_type_var(1)], - vec![int_type_var(0)], - ); - - let widen_poly = int_polytype(2, vec![int_type_var(0)], vec![int_type_var(1)]); - let narrow_poly = int_polytype( - 2, - vec![int_type_var(0)], - vec![sum_with_error(int_type_var(1))], - ); - let mut extension = Extension::new_with_reqs( - EXTENSION_ID, - ExtensionSet::singleton(&super::int_types::EXTENSION_ID), - ); - - extension - .add_op( - "iwiden_u".into(), - "widen an unsigned integer to a wider one with the same value".to_owned(), - CustomValidator::new_with_validator(widen_poly.clone(), IOValidator { f_gt_s: false }), - ) - .unwrap(); - - extension - .add_op( - "iwiden_s".into(), - "widen a signed integer to a wider one with the same value".to_owned(), - CustomValidator::new_with_validator(widen_poly, IOValidator { f_gt_s: false }), - ) - .unwrap(); - extension - .add_op( - "inarrow_u".into(), - "narrow an unsigned integer to a narrower one with the same value if possible" - .to_owned(), - CustomValidator::new_with_validator(narrow_poly.clone(), IOValidator { f_gt_s: true }), - ) - .unwrap(); - extension - .add_op( - "inarrow_s".into(), - "narrow a signed integer to a narrower one with the same value if possible".to_owned(), - CustomValidator::new_with_validator(narrow_poly, IOValidator { f_gt_s: true }), - ) - .unwrap(); - extension - .add_op( - "itobool".into(), - "convert to bool (1 is true, 0 is false)".to_owned(), - itob_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "ifrombool".into(), - "convert from bool (1 is true, 0 is false)".to_owned(), - btoi_sig.clone(), - ) - .unwrap(); - extension - .add_op("ieq".into(), "equality test".to_owned(), icmp_sig.clone()) - .unwrap(); - extension - .add_op("ine".into(), "inequality test".to_owned(), icmp_sig.clone()) - .unwrap(); - extension - .add_op( - "ilt_u".into(), - "\"less than\" as unsigned integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "ilt_s".into(), - "\"less than\" as signed integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "igt_u".into(), - "\"greater than\" as unsigned integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "igt_s".into(), - "\"greater than\" as signed integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "ile_u".into(), - "\"less than or equal\" as unsigned integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "ile_s".into(), - "\"less than or equal\" as signed integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "ige_u".into(), - "\"greater than or equal\" as unsigned integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "ige_s".into(), - "\"greater than or equal\" as signed integers".to_owned(), - icmp_sig.clone(), - ) - .unwrap(); - extension - .add_op( - "imax_u".into(), - "maximum of unsigned integers".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "imax_s".into(), - "maximum of signed integers".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "imin_u".into(), - "minimum of unsigned integers".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "imin_s".into(), - "minimum of signed integers".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "iadd".into(), - "addition modulo 2^N (signed and unsigned versions are the same op)".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "isub".into(), - "subtraction modulo 2^N (signed and unsigned versions are the same op)".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "ineg".into(), - "negation modulo 2^N (signed and unsigned versions are the same op)".to_owned(), - iunop_sig(), - ) - .unwrap(); - extension - .add_op( - "imul".into(), - "multiplication modulo 2^N (signed and unsigned versions are the same op)".to_owned(), - ibinop_sig(), - ) - .unwrap(); - extension - .add_op( - "idivmod_checked_u".into(), - "given unsigned integers 0 <= n < 2^N, 0 <= m < 2^M, generates unsigned q, r where \ - q*m+r=n, 0<=r Type { +pub(super) fn int_tv(var_id: usize) -> Type { Type::new_extension( EXTENSION .get_type(&INT_TYPE_ID) From 8a4c3a040e21cd7f62ba064b0e198983bb188bb6 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Thu, 30 Nov 2023 10:46:43 +0000 Subject: [PATCH 2/6] feat: IntOpType convenience struct --- src/ops/custom.rs | 17 ++- src/std_extensions/arithmetic/int_ops.rs | 155 ++++++++++++++++++----- 2 files changed, 141 insertions(+), 31 deletions(-) diff --git a/src/ops/custom.rs b/src/ops/custom.rs index f5c013d60..b179a7bb2 100644 --- a/src/ops/custom.rs +++ b/src/ops/custom.rs @@ -10,6 +10,7 @@ use crate::hugr::{HugrView, NodeType}; use crate::types::{type_param::TypeArg, FunctionType}; use crate::{Hugr, Node}; +use super::dataflow::DataflowOpTrait; use super::tag::OpTag; use super::{LeafOp, OpTrait, OpType}; @@ -74,7 +75,7 @@ impl ExternalOp { pub fn description(&self) -> &str { match self { Self::Opaque(op) => op.description.as_str(), - Self::Extension(ExtensionOp { def, .. }) => def.description(), + Self::Extension(ext_op) => DataflowOpTrait::description(ext_op), } } @@ -86,7 +87,7 @@ impl ExternalOp { .signature .clone() .expect("Op should have been serialized with signature."), - Self::Extension(ExtensionOp { signature, .. }) => signature.clone(), + Self::Extension(ext_op) => ext_op.signature(), } } } @@ -170,6 +171,18 @@ impl PartialEq for ExtensionOp { } } +impl DataflowOpTrait for ExtensionOp { + const TAG: OpTag = OpTag::Leaf; + + fn description(&self) -> &str { + self.def().description() + } + + fn signature(&self) -> FunctionType { + self.signature.clone() + } +} + impl Eq for ExtensionOp {} /// An opaquely-serialized op that refers to an as-yet-unresolved [`OpDef`] diff --git a/src/std_extensions/arithmetic/int_ops.rs b/src/std_extensions/arithmetic/int_ops.rs index 008c5d988..7fa006c00 100644 --- a/src/std_extensions/arithmetic/int_ops.rs +++ b/src/std_extensions/arithmetic/int_ops.rs @@ -2,8 +2,12 @@ use super::int_types::{get_log_width, int_tv, LOG_WIDTH_TYPE_PARAM}; use crate::extension::prelude::{sum_with_error, BOOL_T}; -use crate::extension::simple_op::MakeOpDef; -use crate::extension::{CustomValidator, OpDef, SignatureFunc, ValidateJustArgs}; +use crate::extension::simple_op::{MakeExtensionOp, MakeOpDef, MakeRegisteredOp, OpLoadError}; +use crate::extension::{ + CustomValidator, ExtensionRegistry, OpDef, SignatureFunc, ValidateJustArgs, PRELUDE, +}; +use crate::ops::custom::ExtensionOp; +use crate::ops::OpName; use crate::type_row; use crate::types::{FunctionType, PolyFuncType}; use crate::utils::collect_array; @@ -14,6 +18,7 @@ use crate::{ }; use lazy_static::lazy_static; +use smol_str::SmolStr; use strum_macros::{EnumIter, EnumString, IntoStaticStr}; /// The extension identifier. @@ -39,7 +44,7 @@ impl ValidateJustArgs for IOValidator { /// Logic extension operation definitions. #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, EnumIter, IntoStaticStr, EnumString)] #[allow(missing_docs, non_camel_case_types)] -pub enum IntOps { +pub enum IntOpDef { iwiden_u, iwiden_s, inarrow_u, @@ -87,13 +92,13 @@ pub enum IntOps { irotr, } -impl MakeOpDef for IntOps { +impl MakeOpDef for IntOpDef { fn from_def(op_def: &OpDef) -> Result { crate::extension::simple_op::try_from_name(op_def.name()) } fn signature(&self) -> SignatureFunc { - use IntOps::*; + use IntOpDef::*; match self { iwiden_s | iwiden_u => CustomValidator::new_with_validator( int_polytype(2, vec![int_tv(0)], vec![int_tv(1)]), @@ -152,7 +157,7 @@ impl MakeOpDef for IntOps { } fn description(&self) -> String { - use IntOps::*; + use IntOpDef::*; match self { iwiden_u => "widen an unsigned integer to a wider one with the same value", @@ -241,18 +246,91 @@ lazy_static! { ExtensionSet::singleton(&super::int_types::EXTENSION_ID), ); - IntOps::load_all_ops(&mut extension).unwrap(); + IntOpDef::load_all_ops(&mut extension).unwrap(); extension }; + + /// Registry of extensions required to validate integer operations. + pub static ref INT_OPS_REGISTRY: ExtensionRegistry = ExtensionRegistry::try_new([ + PRELUDE.to_owned(), + super::int_types::EXTENSION.to_owned(), + EXTENSION.to_owned(), + ]) + .unwrap(); +} + +/// Concrete integer operation with either one or two integer widths set. +#[derive(Debug, Clone, PartialEq)] +pub struct IntOpType { + def: IntOpDef, + first_width: u64, + second_width: Option, +} + +impl OpName for IntOpType { + fn name(&self) -> SmolStr { + self.def.name() + } +} +impl MakeExtensionOp for IntOpType { + fn from_extension_op(ext_op: &ExtensionOp) -> Result { + let def = IntOpDef::from_def(ext_op.def())?; + let (first_width, second_width) = match *ext_op.args() { + [TypeArg::BoundedNat { n }] => (n, None), + [TypeArg::BoundedNat { n }, TypeArg::BoundedNat { n: n2 }] => (n, Some(n2)), + _ => return Err(SignatureError::InvalidTypeArgs.into()), + }; + Ok(Self { + def, + first_width, + second_width, + }) + } + + fn type_args(&self) -> Vec { + [Some(self.first_width), self.second_width] + .iter() + .flatten() + .map(|&n| TypeArg::BoundedNat { n }) + .collect() + } +} + +impl MakeRegisteredOp for IntOpType { + fn extension_id(&self) -> ExtensionId { + EXTENSION_ID.to_owned() + } + + fn registry<'s, 'r: 's>(&'s self) -> &'r ExtensionRegistry { + &INT_OPS_REGISTRY + } +} + +impl IntOpDef { + /// Initialize a concrete [IntOpType] from a [IntOpDef] which requires one + /// integer width set. + pub fn one_width(self, width: u64) -> IntOpType { + IntOpType { + def: self, + first_width: width, + second_width: None, + } + } + /// Initialize a concrete [IntOpType] from a [IntOpDef] which requires two + /// integer widths set. + pub fn two_widths(self, first_width: u64, second_width: u64) -> IntOpType { + IntOpType { + def: self, + first_width, + second_width: Some(second_width), + } + } } #[cfg(test)] mod test { - use crate::{ - extension::{ExtensionRegistry, PRELUDE}, - std_extensions::arithmetic::int_types::int_type, - }; + use crate::{ops::dataflow::DataflowOpTrait, std_extensions::arithmetic::int_types::int_type}; use super::*; @@ -271,33 +349,52 @@ mod test { } #[test] fn test_binary_signatures() { - let iwiden_s = EXTENSION.get_op("iwiden_s").unwrap(); - let reg = ExtensionRegistry::try_new([ - EXTENSION.to_owned(), - super::super::int_types::EXTENSION.to_owned(), - PRELUDE.to_owned(), - ]) - .unwrap(); assert_eq!( - iwiden_s.compute_signature(&[ta(3), ta(4)], ®).unwrap(), + // iwiden_s + // .compute_signature(&[ta(3), ta(4)], &INT_OPS_REGISTRY) + // .unwrap(), + IntOpDef::iwiden_s + .two_widths(3, 4) + .to_extension_op() + .unwrap() + .signature(), FunctionType::new(vec![int_type(ta(3))], vec![int_type(ta(4))],) ); - let iwiden_u = EXTENSION.get_op("iwiden_u").unwrap(); - iwiden_u - .compute_signature(&[ta(4), ta(3)], ®) - .unwrap_err(); + // let iwiden_u = EXTENSION.get_op("iwiden_u").unwrap(); + // iwiden_u + // .compute_signature(&[ta(4), ta(3)], &INT_OPS_REGISTRY) + // .unwrap_err(); - let inarrow_s = EXTENSION.get_op("inarrow_s").unwrap(); + assert!(IntOpDef::iwiden_u + .two_widths(4, 3) + .to_extension_op() + .is_none()); assert_eq!( - inarrow_s.compute_signature(&[ta(2), ta(1)], ®).unwrap(), + IntOpDef::inarrow_s + .two_widths(2, 1) + .to_extension_op() + .unwrap() + .signature(), FunctionType::new(vec![int_type(ta(2))], vec![sum_with_error(int_type(ta(1)))],) ); - let inarrow_u = EXTENSION.get_op("inarrow_u").unwrap(); - inarrow_u - .compute_signature(&[ta(1), ta(2)], ®) - .unwrap_err(); + assert!(IntOpDef::inarrow_u + .two_widths(1, 2) + .to_extension_op() + .is_none()); + } + + #[test] + fn test_conversions() { + let o = IntOpDef::itobool.one_width(5); + assert!(IntOpDef::itobool + .two_widths(1, 2) + .to_extension_op() + .is_none()); + let ext_op = o.clone().to_extension_op().unwrap(); + + assert_eq!(IntOpType::from_extension_op(&ext_op).unwrap(), o); } } From 468e907ad904b5d22bf7767c483cfe64f4902913 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Thu, 30 Nov 2023 16:47:47 +0000 Subject: [PATCH 3/6] better constructor names --- src/std_extensions/arithmetic/int_ops.rs | 25 ++++++++---------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/std_extensions/arithmetic/int_ops.rs b/src/std_extensions/arithmetic/int_ops.rs index 7fa006c00..6a7991d1c 100644 --- a/src/std_extensions/arithmetic/int_ops.rs +++ b/src/std_extensions/arithmetic/int_ops.rs @@ -310,7 +310,7 @@ impl MakeRegisteredOp for IntOpType { impl IntOpDef { /// Initialize a concrete [IntOpType] from a [IntOpDef] which requires one /// integer width set. - pub fn one_width(self, width: u64) -> IntOpType { + pub fn with_width(self, width: u64) -> IntOpType { IntOpType { def: self, first_width: width, @@ -319,7 +319,7 @@ impl IntOpDef { } /// Initialize a concrete [IntOpType] from a [IntOpDef] which requires two /// integer widths set. - pub fn two_widths(self, first_width: u64, second_width: u64) -> IntOpType { + pub fn with_two_widths(self, first_width: u64, second_width: u64) -> IntOpType { IntOpType { def: self, first_width, @@ -350,30 +350,21 @@ mod test { #[test] fn test_binary_signatures() { assert_eq!( - // iwiden_s - // .compute_signature(&[ta(3), ta(4)], &INT_OPS_REGISTRY) - // .unwrap(), IntOpDef::iwiden_s - .two_widths(3, 4) + .with_two_widths(3, 4) .to_extension_op() .unwrap() .signature(), FunctionType::new(vec![int_type(ta(3))], vec![int_type(ta(4))],) ); - - // let iwiden_u = EXTENSION.get_op("iwiden_u").unwrap(); - // iwiden_u - // .compute_signature(&[ta(4), ta(3)], &INT_OPS_REGISTRY) - // .unwrap_err(); - assert!(IntOpDef::iwiden_u - .two_widths(4, 3) + .with_two_widths(4, 3) .to_extension_op() .is_none()); assert_eq!( IntOpDef::inarrow_s - .two_widths(2, 1) + .with_two_widths(2, 1) .to_extension_op() .unwrap() .signature(), @@ -381,16 +372,16 @@ mod test { ); assert!(IntOpDef::inarrow_u - .two_widths(1, 2) + .with_two_widths(1, 2) .to_extension_op() .is_none()); } #[test] fn test_conversions() { - let o = IntOpDef::itobool.one_width(5); + let o = IntOpDef::itobool.with_width(5); assert!(IntOpDef::itobool - .two_widths(1, 2) + .with_two_widths(1, 2) .to_extension_op() .is_none()); let ext_op = o.clone().to_extension_op().unwrap(); From df3995ab826f01cc792a3dce595b7e20bb9b73db Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Thu, 30 Nov 2023 16:48:22 +0000 Subject: [PATCH 4/6] assert string --- src/std_extensions/arithmetic/int_ops.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/std_extensions/arithmetic/int_ops.rs b/src/std_extensions/arithmetic/int_ops.rs index 6a7991d1c..fa76adfc7 100644 --- a/src/std_extensions/arithmetic/int_ops.rs +++ b/src/std_extensions/arithmetic/int_ops.rs @@ -357,10 +357,13 @@ mod test { .signature(), FunctionType::new(vec![int_type(ta(3))], vec![int_type(ta(4))],) ); - assert!(IntOpDef::iwiden_u - .with_two_widths(4, 3) - .to_extension_op() - .is_none()); + assert!( + IntOpDef::iwiden_u + .with_two_widths(4, 3) + .to_extension_op() + .is_none(), + "type arguments invalid" + ); assert_eq!( IntOpDef::inarrow_s @@ -380,10 +383,13 @@ mod test { #[test] fn test_conversions() { let o = IntOpDef::itobool.with_width(5); - assert!(IntOpDef::itobool - .with_two_widths(1, 2) - .to_extension_op() - .is_none()); + assert!( + IntOpDef::itobool + .with_two_widths(1, 2) + .to_extension_op() + .is_none(), + "type arguments invalid" + ); let ext_op = o.clone().to_extension_op().unwrap(); assert_eq!(IntOpType::from_extension_op(&ext_op).unwrap(), o); From 356e201e2ffe7bfc03142ab3b5d80807d74a44ce Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Fri, 1 Dec 2023 11:23:33 +0000 Subject: [PATCH 5/6] fix docstring --- src/std_extensions/arithmetic/int_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_extensions/arithmetic/int_types.rs b/src/std_extensions/arithmetic/int_types.rs index f89a5ee52..b683f075f 100644 --- a/src/std_extensions/arithmetic/int_types.rs +++ b/src/std_extensions/arithmetic/int_types.rs @@ -203,7 +203,7 @@ lazy_static! { pub static ref EXTENSION: Extension = extension(); } -/// get an integer type variable, given the integer type definition +/// get an integer type with width corresponding to a type variable with id `var_size` pub(super) fn int_tv(var_id: usize) -> Type { Type::new_extension( EXTENSION From 9e9d0af5f3e3f2f368a2ce185f8b14dc5f9a030d Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Fri, 1 Dec 2023 11:25:45 +0000 Subject: [PATCH 6/6] fix fix docstring Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- src/std_extensions/arithmetic/int_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std_extensions/arithmetic/int_types.rs b/src/std_extensions/arithmetic/int_types.rs index b683f075f..f45d93964 100644 --- a/src/std_extensions/arithmetic/int_types.rs +++ b/src/std_extensions/arithmetic/int_types.rs @@ -203,7 +203,7 @@ lazy_static! { pub static ref EXTENSION: Extension = extension(); } -/// get an integer type with width corresponding to a type variable with id `var_size` +/// get an integer type with width corresponding to a type variable with id `var_id` pub(super) fn int_tv(var_id: usize) -> Type { Type::new_extension( EXTENSION