Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hugr-py cannot load CFG edges json-serialized from Rust #1923

Open
acl-cqc opened this issue Feb 18, 2025 · 1 comment · May be fixed by #1924
Open

hugr-py cannot load CFG edges json-serialized from Rust #1923

acl-cqc opened this issue Feb 18, 2025 · 1 comment · May be fixed by #1924

Comments

@acl-cqc
Copy link
Contributor

acl-cqc commented Feb 18, 2025

Rust produces edges something like:

"edges":[[[1,null],[4,null]],[[1,null],[3,null]],[[3,null],[2,null]],[[3,null],[4,null]],[[4,null],[2,null]],

...(where nodes 1-4 are DataflowBlocks - note the two [1, null] outports for successors 0 and 1 of the same block)

Whereas hugr-py produces

"edges":[[[1,0],[5,0]],[[1,1],[10,0]],[[5,0],[4,0]],[[10,0],[4,0]]],

...(eliding non-block edges)

In practice, both roundtrip, and Rust is able to load hugr-py output, but not vice versa.

@acl-cqc
Copy link
Contributor Author

acl-cqc commented Feb 21, 2025

This diff "fixes" the Rust by making it output the same as hugr-py:

--- a/hugr-core/src/hugr/serialize.rs
+++ b/hugr-core/src/hugr/serialize.rs
@@ -183,7 +183,13 @@ impl TryFrom<&Hugr> for SerHugrLatest {
             let op = hugr.get_optype(node);
             let is_value_port = offset < op.value_port_count(dir);
             let is_static_input = op.static_port(dir).map_or(false, |p| p.index() == offset);
-            let offset = (is_value_port || is_static_input).then_some(offset as u16);
+            let offset = (is_value_port
+                || is_static_input
+                || matches!(
+                    op.port_kind(crate::Port::new(dir, offset)),
+                    Some(crate::types::EdgeKind::ControlFlow)
+                ))
+            .then_some(offset as u16);
             (node_rekey[&node], offset)
         };

although I wonder if we could avoid is_value_port and is_static_input (misnamed, should be is-static-port) altogether as these seem to duplicate logic in OpType::port_kind - maybe just something like matches!(op.port_kind(...), EdgeKind::Value(_) | EdgeKind::Static | EdgeKind::ControlFlow)

@acl-cqc acl-cqc linked a pull request Feb 21, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant