-
Notifications
You must be signed in to change notification settings - Fork 6
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
feat: Export the core data structures to a model representation #1414
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1414 +/- ##
==========================================
- Coverage 87.55% 86.44% -1.11%
==========================================
Files 119 120 +1
Lines 20781 21047 +266
Branches 18053 18319 +266
==========================================
Hits 18194 18194
- Misses 1802 2068 +266
Partials 785 785
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Lukas - a few thoughts.
Presumably if we go with a system of "constraints", in order to express the expressible parts of binary compute_signature
, we'll also need to use the hugr-model for serializaiton of extension sets...
hugr: &'a Hugr, | ||
/// The module that is being built. | ||
module: model::Module, | ||
/// Mapping from ports to edge indices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense after I've looked at get_edge_id
but a bit more explanation here would help: this is where people will look for docs first!
TypeArg::BoundedNat { n } => ctx.make_term(model::Term::Nat(*n)), | ||
TypeArg::String { arg } => ctx.make_term(model::Term::Str(arg.into())), | ||
TypeArg::Sequence { elems } => { | ||
// For now we assume that the sequence is meant to be a list. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, yah this is the tricky bit. I admit that none of the options seem great here.
- Add an ExtensionRegistry to the Context. This doesn't seem to bad, but (although I think necessary) is not sufficient - you also need to pass a TypeParam around, with recursive calls passing an inner TypeParam obtained by destructuring the outer one (
panic
if TypeParam and TypeArg doesn't correspond, as this should have been detected byvalidate
). Two possible ways:- add a TypeParam to the Context, or
- (I suspect better) define a new trait export-with-TypeParam
- Change TypeArg to distinguish between List and Tuple
- Change the model not to distinguish between List and Tuple.
(1.) works, has least fallout elsewhere, but is the greatest "yeuch" here. (2.) is most disruptive to existing code. I'll leave you to think about (3.)...
One could argue that if we aren't prepared to make such awkward format conversions as (1.), then the model has failed in its primary purpose of decoupling serialization format from core/Rust-struct representation
hugr-core/src/types.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -0,0 +1,5 @@ | |||
//! The data model of the HUGR intermediate representation. | |||
//! This crate defines data structures that capture the structure of a HUGR graph and | |||
//! all its associated information in a form that can be stored on disk. The data structures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: does anyone still use "disk"s nowadays? :)
perhaps something like "in a form designed for simple and efficient serialization, rather than traversal or modification"??? Or we could say this is for serialization, storage and interchange?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's used metaphorically, like the floppy disk symbol meaning "save" although it's most likely not being saved on a floppy disk.
/// The name of the term. | ||
pub name: Symbol, | ||
/// Arguments to the term. | ||
pub args: TinyVec<[TermId; 3]>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment about triples
} | ||
|
||
pub fn make_term(&mut self, term: model::Term) -> model::TermId { | ||
let index = self.module.terms.len(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the place to do hash-consing?? (I.e. look for an existing Term
that matches the suppiled, and if so then return that TermId rather than pushing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be useful to associate ids with uses, i.e be able to trace problems back to the source by figuring out which instance of a term we're looking at. I'm looking in to hashconsing at serialisation time, and preserving all the ids that point to the same term. We can apply this to the model separately without changing the model behaviour I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have experimented with doing hashconsing here: e4ef7be
I think it's worthwhile.
//! | ||
//! # Terms | ||
//! | ||
//! Terms form a meta language that is used to describe types, parameters and metadata that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a design point that has probably been addressed elsewhere, but do we really want structured metadata like this?
Ok, I can see many use cases for metadata which does contain....Hugr-defined things. But not necessarily Terms - maybe Hugrs or NodeId's or other things. And, how is unstructured metadata represented? (I see that a MetaItem contains exactly one Term, I haven't seen the alternative - am I looking in the wrong place?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zrho made the point that if what we want is unstructured json you can just use the "string" metadata type always. I personally favour structure only enough structure in metadata to allow for reserved key names we can check for, and fully unstructured payloads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want unstructured metadata, you can still put it into a string. Structured metadata allows validation via typechecking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah OK yes String
is good, right
|
||
/// The type of the port. | ||
/// | ||
/// This must be a term of type `Type`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, will be the same for all Port
s with the same edge
/// Constraints on the parameters of the scheme. | ||
/// | ||
/// All parameters are available as variables within the constraints. | ||
/// The constraints must be terms of type `Constraint`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right - I'm puzzled here. I don't see any enum Term
variants that have type Constraint
; I see only one for the type of Constraints, and I can't understand how that would be used. Am I missing something, looking at this the wrong way, or is this just WIP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all a big WIP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some housekeeping needed when adding a new package:
- Add a README. Just copy the template from the other crates.
- Add this to
release-plz.toml
. We'll still need to do some manual deployment before the nexthugr-core
release, asrelease-plz
does not have permission to create new packages.Also add it to the[[package]] name = "hugr-cli" release = true
changelog_include
forhugr
- Add the new directory it to
.github/change-filters.yml
edition.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
license.workspace = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
license.workspace = true | |
license.workspace = true | |
readme = "README.md" | |
documentation = "https://docs.rs/hugr-model/" | |
description = "Serializable model for Quantinuum's HUGR" | |
keywords = ["Quantum", "Quantinuum"] | |
categories = ["compilers"] |
This PR introduces a draft for the
hugr-model
data structures together with a function to export aHugr
into this format.