Skip to content

Commit

Permalink
refactor!: clearer OpType port/kind method names
Browse files Browse the repository at this point in the history
And addds `static_input_port` method.
Closes Clean up OpType methods #495
  • Loading branch information
ss2165 committed Nov 13, 2023
1 parent ce36b5a commit 0be1294
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/hugr/hugrmut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,12 @@ impl<T: RootTagged<RootHandle = Node> + AsMut<Hugr>> HugrMut for T {
) -> Result<(OutgoingPort, IncomingPort), HugrError> {
let src_port = self
.get_optype(src)
.other_port_index(Direction::Outgoing)
.other_output_port()
.expect("Source operation has no non-dataflow outgoing edges")
.as_outgoing()?;
let dst_port = self
.get_optype(dst)
.other_port_index(Direction::Incoming)
.other_input_port()
.expect("Destination operation has no non-dataflow incoming edges")
.as_incoming()?;
self.connect(src, src_port, dst, dst_port)?;
Expand Down
2 changes: 1 addition & 1 deletion src/hugr/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl TryFrom<SerHugrV0> for Hugr {
None => {
let op_type = hugr.get_optype(node);
op_type
.other_port_index(dir)
.other_port(dir)
.ok_or(HUGRSerializationError::MissingPortOffset {
node,
op_type: op_type.clone(),
Expand Down
4 changes: 2 additions & 2 deletions src/hugr/views/sibling_subgraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,13 +596,13 @@ fn get_input_output_ports<H: HugrView>(hugr: &H) -> (IncomingPorts, OutgoingPort
/// Whether a port is linked to a state order edge.
fn is_order_edge<H: HugrView>(hugr: &H, node: Node, port: Port) -> bool {
let op = hugr.get_optype(node);
op.other_port_index(port.direction()) == Some(port) && hugr.is_linked(node, port)
op.other_port(port.direction()) == Some(port) && hugr.is_linked(node, port)
}

/// Whether node has a non-df linked port in the given direction.
fn has_other_edge<H: HugrView>(hugr: &H, node: Node, dir: Direction) -> bool {
let op = hugr.get_optype(node);
op.other_port(dir).is_some() && hugr.is_linked(node, op.other_port_index(dir).unwrap())
op.other_port_kind(dir).is_some() && hugr.is_linked(node, op.other_port(dir).unwrap())
}

/// Errors that can occur while constructing a [`SimpleReplacement`].
Expand Down
43 changes: 32 additions & 11 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ impl Default for OpType {
}

impl OpType {
/// The edge kind for the non-dataflow or constant-input ports of the
/// The edge kind for the non-dataflow or constant ports of the
/// operation, not described by the signature.
///
/// If not None, a single extra multiport of that kind will be present on
/// the given direction.
pub fn other_port(&self, dir: Direction) -> Option<EdgeKind> {
pub fn other_port_kind(&self, dir: Direction) -> Option<EdgeKind> {
match dir {
Direction::Incoming => self.other_input(),
Direction::Outgoing => self.other_output(),
Expand All @@ -84,23 +84,20 @@ impl OpType {
let port_count = signature.port_count(dir);
if port.index() < port_count {
signature.get(port).cloned().map(EdgeKind::Value)
} else if port.index() == port_count
&& dir == Direction::Incoming
&& OpTag::StaticInput.is_superset(self.tag())
{
} else if Some(port) == self.static_input_port() {
Some(EdgeKind::Static(static_in_type(self)))
} else {
self.other_port(dir)
self.other_port_kind(dir)
}
}

/// The non-dataflow port for the operation, not described by the signature.
/// See `[OpType::other_port]`.
/// See `[OpType::other_port_kind]`.
///
/// Returns None if there is no such port, or if the operation defines multiple non-dataflow ports.
pub fn other_port_index(&self, dir: Direction) -> Option<Port> {
pub fn other_port(&self, dir: Direction) -> Option<Port> {
let non_df_count = self.non_df_port_count(dir).unwrap_or(1);
if self.other_port(dir).is_some() && non_df_count == 1 {
if self.other_port_kind(dir).is_some() && non_df_count == 1 {
// if there is a static input it comes before the non_df_ports
let static_input =
(dir == Direction::Incoming && OpTag::StaticInput.is_superset(self.tag())) as usize;
Expand All @@ -114,10 +111,34 @@ impl OpType {
}
}

/// The non-dataflow input port for the operation, not described by the signature.
/// See `[OpType::other_port]`.
pub fn other_input_port(&self) -> Option<Port> {
self.other_port(Direction::Incoming)
}

/// The non-dataflow input port for the operation, not described by the signature.
/// See `[OpType::other_port]`.
pub fn other_output_port(&self) -> Option<Port> {
self.other_port(Direction::Outgoing)
}

/// If the op has a static input (Call and LoadConstant), the port of that input.
pub fn static_input_port(&self) -> Option<Port> {
match self {
OpType::Call(call) => Some(Port::new(
Direction::Incoming,
call.called_function_type().input_count(),
)),
OpType::LoadConstant(_) => Some(Port::new(Direction::Incoming, 0)),
_ => None,
}
}

/// Returns the number of ports for the given direction.
pub fn port_count(&self, dir: Direction) -> usize {
let signature = self.signature();
let has_other_ports = self.other_port(dir).is_some();
let has_other_ports = self.other_port_kind(dir).is_some();
let non_df_count = self
.non_df_port_count(dir)
.unwrap_or(has_other_ports as usize);
Expand Down

0 comments on commit 0be1294

Please sign in to comment.