Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ bitvec = "1.0.1"
capnp = "0.20.6"
cgmath = "0.18.0"
cool_asserts = "2.0.3"
delegate = "0.13.3"
delegate = "0.13.4"
derive_more = "1.0.0"
downcast-rs = "2.0.1"
enum_dispatch = "0.3.11"
Expand Down Expand Up @@ -94,7 +94,7 @@ wyhash = "0.6.0"
# These public dependencies usually require breaking changes downstream, so we
# try to be as permissive as possible.
pyo3 = ">= 0.23.4, < 0.25"
portgraph = { version = "0.14.1" }
portgraph = { version = "0.15.0" }
petgraph = { version = ">= 0.8.1, < 0.9", default-features = false }

[profile.dev.package]
Expand Down
4 changes: 2 additions & 2 deletions hugr-core/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct Node {
)]
#[serde(transparent)]
pub struct Port {
offset: portgraph::PortOffset,
offset: portgraph::PortOffset<u32>,
}

/// A trait for getting the undirected index of a port.
Expand Down Expand Up @@ -139,7 +139,7 @@ impl Port {

/// Returns the port as a portgraph `PortOffset`.
#[inline]
pub(crate) fn pg_offset(self) -> portgraph::PortOffset {
pub(crate) fn pg_offset(self) -> portgraph::PortOffset<u32> {
self.offset
}
}
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/hugr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use crate::{Direction, Node};
#[derive(Clone, Debug, PartialEq)]
pub struct Hugr {
/// The graph encoding the adjacency structure of the HUGR.
graph: MultiPortGraph,
graph: MultiPortGraph<u32, u32, u32>,

/// The node hierarchy.
hierarchy: Hierarchy,
Expand Down
6 changes: 3 additions & 3 deletions hugr-core/src/hugr/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::ops::handle::NodeHandle;
/// view.
pub trait HugrInternals {
/// The portgraph graph structure returned by [`HugrInternals::region_portgraph`].
type RegionPortgraph<'p>: LinkView<LinkEndpoint: Eq> + Clone + 'p
type RegionPortgraph<'p>: LinkView<LinkEndpoint: Eq, PortOffsetBase = u32> + Clone + 'p
where
Self: 'p;

Expand Down Expand Up @@ -109,7 +109,7 @@ impl<N: HugrNode> PortgraphNodeMap<N> for std::collections::HashMap<N, Node> {

impl HugrInternals for Hugr {
type RegionPortgraph<'p>
= &'p MultiPortGraph
= &'p MultiPortGraph<u32, u32, u32>
where
Self: 'p;

Expand Down Expand Up @@ -397,7 +397,7 @@ impl Hugr {
pub fn into_region_portgraph(
self,
parent: Node,
) -> portgraph::view::FlatRegion<'static, MultiPortGraph> {
) -> portgraph::view::FlatRegion<'static, MultiPortGraph<u32, u32, u32>> {
let root = parent.into_portgraph();
let Self {
graph, hierarchy, ..
Expand Down
40 changes: 22 additions & 18 deletions hugr-core/src/hugr/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ impl<T: DeserializeOwned> Versioned<T> {

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
struct NodeSer {
parent: Node,
/// Node index of the parent.
parent: usize,
#[serde(flatten)]
op: OpType,
}
Expand All @@ -89,7 +90,7 @@ struct SerHugrLatest {
/// For each node: (parent, `node_operation`)
nodes: Vec<NodeSer>,
/// for each edge: (src, `src_offset`, tgt, `tgt_offset`)
edges: Vec<[(Node, Option<u16>); 2]>,
edges: Vec<[(usize, Option<u32>); 2]>,
/// for each node: (metadata)
#[serde(default)]
metadata: Option<Vec<Option<NodeMetadataMap>>>,
Expand All @@ -101,7 +102,7 @@ struct SerHugrLatest {
/// For backwards compatibility, if `None` the entrypoint is set to the root
/// of the node hierarchy.
#[serde(default)]
entrypoint: Option<Node>,
entrypoint: Option<usize>,
}

/// Errors that can occur while serializing a HUGR.
Expand All @@ -113,7 +114,7 @@ pub enum HUGRSerializationError {
AttachError(#[from] AttachError),
/// Failed to add edge.
#[error("Failed to build edge when deserializing: {0}.")]
LinkError(#[from] LinkError),
LinkError(#[from] LinkError<u32>),
/// Edges without port offsets cannot be present in operations without non-dataflow ports.
#[error(
"Cannot connect an {dir:?} edge without port offset to node {node} with operation type {op_type}."
Expand Down Expand Up @@ -200,7 +201,7 @@ impl TryFrom<&Hugr> for SerHugrLatest {
let opt = hugr.get_optype(n);
let new_node = node_rekey[&n].index();
nodes[new_node] = Some(NodeSer {
parent,
parent: parent.index(),
op: opt.clone(),
});
metadata[new_node].clone_from(hugr.metadata.get(n.into_portgraph()));
Expand All @@ -210,13 +211,14 @@ impl TryFrom<&Hugr> for SerHugrLatest {
.collect::<Option<Vec<_>>>()
.expect("Could not reach one of the nodes");

let find_offset = |node: Node, offset: usize, dir: Direction, hugr: &Hugr| {
let op = hugr.get_optype(node);
let is_value_port = offset < op.value_port_count(dir);
let is_static_input = op.static_port(dir).is_some_and(|p| p.index() == offset);
let offset = (is_value_port || is_static_input).then_some(offset as u16);
(node_rekey[&node], offset)
};
let find_offset =
|node: Node, offset: usize, dir: Direction, hugr: &Hugr| -> (usize, Option<u32>) {
let op = hugr.get_optype(node);
let is_value_port = offset < op.value_port_count(dir);
let is_static_input = op.static_port(dir).is_some_and(|p| p.index() == offset);
let offset = (is_value_port || is_static_input).then_some(offset as u32);
(node_rekey[&node].index(), offset)
};

let edges: Vec<_> = hugr
.nodes()
Expand All @@ -240,7 +242,7 @@ impl TryFrom<&Hugr> for SerHugrLatest {
edges,
metadata: Some(metadata),
encoder,
entrypoint: Some(node_rekey[&hugr.entrypoint()]),
entrypoint: Some(node_rekey[&hugr.entrypoint()].index()),
})
}
}
Expand All @@ -263,7 +265,8 @@ impl TryFrom<SerHugrLatest> for Hugr {
op: root_type,
..
} = nodes.next().unwrap();
if root_parent.index() != 0 {
if root_parent != 0 {
let root_parent = portgraph::NodeIndex::new(root_parent).into();
return Err(HUGRSerializationError::FirstNodeNotRoot(root_parent));
}
// if there are any unconnected ports or copy nodes the capacity will be
Expand All @@ -274,21 +277,22 @@ impl TryFrom<SerHugrLatest> for Hugr {
// encoded file did not have a module at the root), we need a function
// to map the node indices.
let padding_nodes = hugr.entrypoint.index();
let hugr_node =
|node: Node| -> Node { portgraph::NodeIndex::new(node.index() + padding_nodes).into() };
let hugr_node = |node: usize| -> Node {
portgraph::NodeIndex::new(node.index() + padding_nodes).into()
};

for node_ser in nodes {
hugr.add_node_with_parent(hugr_node(node_ser.parent), node_ser.op);
}

if let Some(entrypoint) = entrypoint {
hugr.set_entrypoint(entrypoint);
hugr.set_entrypoint(hugr_node(entrypoint));
}

if let Some(metadata) = metadata {
for (node_idx, metadata) in metadata.into_iter().enumerate() {
if let Some(metadata) = metadata {
let node = hugr_node(portgraph::NodeIndex::new(node_idx).into());
let node = hugr_node(node_idx);
hugr.metadata[node.into_portgraph()] = Some(metadata);
}
}
Expand Down
12 changes: 3 additions & 9 deletions hugr-core/src/hugr/serialize/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,6 @@ fn ser_roundtrip_check_schema<TSer: Serialize, TDeser: serde::de::DeserializeOwn

/// Serialize a Hugr and check that it is valid against the schema.
///
/// NOTE: The schema definition is currently broken, so this check always succeeds.
/// See <https://github.com/CQCL/hugr/issues/2401>
///
/// # Panics
///
/// Panics if the serialization fails or if the schema validation fails.
Expand Down Expand Up @@ -303,7 +300,7 @@ fn wrong_fields(
}

/// Generate an optype for a node with a matching amount of inputs and outputs.
fn gen_optype(g: &MultiPortGraph, node: portgraph::NodeIndex) -> OpType {
fn gen_optype(g: &MultiPortGraph<u32, u32, u32>, node: portgraph::NodeIndex) -> OpType {
let inputs = g.num_inputs(node);
let outputs = g.num_outputs(node);
match (inputs == 0, outputs == 0) {
Expand Down Expand Up @@ -610,7 +607,7 @@ fn roundtrip_polyfunctype_varlen(#[case] poly_func_type: PolyFuncTypeRV) {
#[case(ops::CallIndirect { signature : Signature::new_endo(vec![bool_t()]) })]
fn roundtrip_optype(#[case] optype: impl Into<OpType> + std::fmt::Debug) {
check_testing_roundtrip(NodeSer {
parent: portgraph::NodeIndex::new(0).into(),
parent: 0,
op: optype.into(),
});
}
Expand Down Expand Up @@ -639,10 +636,7 @@ mod proptest {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(
(0..i32::MAX as usize).prop_map(|x| portgraph::NodeIndex::new(x).into()),
any::<OpType>(),
)
((0..i32::MAX as usize), any::<OpType>())
.prop_map(|(parent, op)| {
if let OpType::ExtensionOp(ext_op) = op {
let opaque: OpaqueOp = ext_op.into();
Expand Down
4 changes: 2 additions & 2 deletions hugr-core/src/hugr/views/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ pub(in crate::hugr) fn edge_style<'a>(
config: MermaidFormatter<'_>,
) -> Box<
dyn FnMut(
<MultiPortGraph as LinkView>::LinkEndpoint,
<MultiPortGraph as LinkView>::LinkEndpoint,
<MultiPortGraph<u32, u32, u32> as LinkView>::LinkEndpoint,
<MultiPortGraph<u32, u32, u32> as LinkView>::LinkEndpoint,
) -> EdgeStyle
+ 'a,
> {
Expand Down
2 changes: 1 addition & 1 deletion hugr-core/src/hugr/views/sibling_subgraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ fn pick_parent<'a, N: HugrNode>(
}

fn make_boundary<'a, H: HugrView>(
region: &impl LinkView,
region: &impl LinkView<PortOffsetBase = u32>,
node_map: &H::RegionPortgraphNodes,
inputs: &'a IncomingPorts<H::Node>,
outputs: &'a OutgoingPorts<H::Node>,
Expand Down
2 changes: 1 addition & 1 deletion hugr-persistent/src/parents_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl<'a> ParentsView<'a> {

impl HugrInternals for ParentsView<'_> {
type RegionPortgraph<'p>
= portgraph::MultiPortGraph
= portgraph::MultiPortGraph<u32, u32, u32>
where
Self: 'p;

Expand Down
18 changes: 17 additions & 1 deletion hugr-persistent/src/state_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub type CommitId = relrc::NodeId;
#[derive(
Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct PatchNode(pub CommitId, pub Node);
pub struct PatchNode(pub CommitId, #[serde(with = "serialize_node")] pub Node);

impl PatchNode {
/// Get the commit ID of the commit that owns this node.
Expand All @@ -57,6 +57,22 @@ impl std::fmt::Display for PatchNode {
}
}

/// Helper for to serialize and deserialize nodes as their usize index.
mod serialize_node {
use hugr_core::{Node, NodeIndex};
use serde::{Deserialize, Serialize};
use serde::{Deserializer, Serializer};

pub fn serialize<S: Serializer>(v: &Node, s: S) -> Result<S::Ok, S::Error> {
v.index().serialize(s)
}

pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Node, D::Error> {
let index = usize::deserialize(d)?;
Ok(Node::from(portgraph::NodeIndex::new(index)))
}
}

mod hidden {
use super::*;

Expand Down
2 changes: 1 addition & 1 deletion hugr-persistent/src/trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl Patch<PersistentHugr> for PersistentReplacement {

impl<R> HugrInternals for PersistentHugr<R> {
type RegionPortgraph<'p>
= portgraph::MultiPortGraph
= portgraph::MultiPortGraph<u32, u32, u32>
where
Self: 'p;

Expand Down
Loading