Skip to content

Commit

Permalink
refactor: Add a hugr-core crate (#1108)
Browse files Browse the repository at this point in the history
Moves all the code from `hugr` into a `hugr-core` subcrate.
This way, `hugr-passes` (and any other new subcrate) can depend on the
core definitions and get reexported in `hugr`.

This PR does not. Change any definition or visibility in the code, as
the renamed files are noisy enough.
In particular, having `hugr-core` will let us unseal `HugrInternals` and
`HugrMutInternals` so they can be used in `tket2`, but that's work for
another PR.

As a bonus, #1100 is no longer a breaking change since we can re-export
the library without a cyclic dependency.

Closes #294
  • Loading branch information
aborgna-q authored May 28, 2024
1 parent 9ff6dce commit bb1565f
Show file tree
Hide file tree
Showing 105 changed files with 269 additions and 159 deletions.
4 changes: 1 addition & 3 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@

# The release PRs that trigger publication to crates.io or PyPI always modify the changelog.
# We require those PRs to be approved by someone with release permissions.
hugr/CHANGELOG.md @aborgna-q @cqc-alec @ss2165
hugr-passes/CHANGELOG.md @aborgna-q @cqc-alec @ss2165
hugr-py/CHANGELOG.md @aborgna-q @cqc-alec @ss2165
**/CHANGELOG.md @aborgna-q @cqc-alec @ss2165
2 changes: 1 addition & 1 deletion .github/change-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

rust:
- "hugr/**"
- "hugr-passes/**"
- "hugr-*/**"
- "Cargo.toml"
- "specification/schema/**"

Expand Down
10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ lto = "thin"

[workspace]
resolver = "2"
members = ["hugr", "hugr-passes"]
default-members = ["hugr", "hugr-passes"]
members = ["hugr", "hugr-core", "hugr-passes"]
default-members = ["hugr", "hugr-core", "hugr-passes"]
default-run = "hugr"

[workspace.package]
rust-version = "1.75"
Expand All @@ -17,6 +18,11 @@ license = "Apache-2.0"
[workspace.lints.rust]
missing_docs = "warn"

[workspace.lints.clippy]
# Unstable check, may cause false positives.
# https://github.com/rust-lang/rust-clippy/issues/5112
debug_assert_with_mut_call = "warn"

[workspace.dependencies]
portgraph = { version = "0.12.0" }
insta = { version = "1.34.0" }
Expand Down
1 change: 1 addition & 0 deletions hugr-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Changelog
66 changes: 66 additions & 0 deletions hugr-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[package]
name = "hugr-core"
version = "0.0.0"
edition = { workspace = true }
rust-version = { workspace = true }

license = { workspace = true }
readme = "README.md"
documentation = "https://docs.rs/hugr/"
homepage = { workspace = true }
repository = { workspace = true }
description = "Quantinuum's Hierarchical Unified Graph Representation"
keywords = ["Quantum", "Quantinuum"]
categories = ["compilers"]

[lints]
workspace = true

[features]
extension_inference = []
cli = ["dep:clap", "dep:clap-stdin"]

[dependencies]
portgraph = { workspace = true, features = ["serde", "petgraph"] }
thiserror = { workspace = true }
regex = { workspace = true }
cgmath = { workspace = true, features = ["serde"] }
num-rational = { workspace = true, features = ["serde"] }
downcast-rs = { workspace = true }
# Rc used here for Extension, but unfortunately we must turn the feature on globally
serde = { workspace = true, features = ["derive", "rc"] }
serde_yaml = { workspace = true }
typetag = { workspace = true }
smol_str = { workspace = true, features = ["serde"] }
derive_more = { workspace = true }
itertools = { workspace = true }
html-escape = { workspace = true }
bitvec = { workspace = true, features = ["serde"] }
enum_dispatch = { workspace = true }
lazy_static = { workspace = true }
petgraph = { workspace = true }
context-iterators = { workspace = true }
serde_json = { workspace = true }
delegate = { workspace = true }
paste = { workspace = true }
strum = { workspace = true }
strum_macros = { workspace = true }
clap = { workspace = true, features = ["derive"], optional = true }
clap-stdin = { workspace = true, optional = true }

[dev-dependencies]
rstest = { workspace = true }
webbrowser = { workspace = true }
urlencoding = { workspace = true }
cool_asserts = { workspace = true }
insta = { workspace = true, features = ["yaml"] }
jsonschema = { workspace = true }
proptest = { workspace = true }
proptest-derive = { workspace = true }
regex-syntax = { workspace = true }
assert_cmd = { workspace = true }
predicates = { workspace = true }
assert_fs = { workspace = true }

# Required for documentation examples
hugr = { path = "../hugr" }
42 changes: 42 additions & 0 deletions hugr-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
![](/hugr/assets/hugr_logo.svg)

hugr-core
===============

[![build_status][]](https://github.com/CQCL/hugr/actions)
[![crates][]](https://crates.io/crates/hugr-core)
[![msrv][]](https://github.com/CQCL/hugr)
[![codecov][]](https://codecov.io/gh/CQCL/hugr)

Internal core definitions for the `hugr` package.
Refer to the [main crate](http://crates.io/crates/hugr) for more information.

Please read the [API documentation here][].

## Experimental Features

- `extension_inference`:
Experimental feature which allows automatic inference of extension usages and
requirements in a HUGR and validation that extensions are correctly specified.
Not enabled by default.

## Recent Changes

See [CHANGELOG][] for a list of changes. The minimum supported rust
version will only change on major releases.

## Development

See [DEVELOPMENT.md](https://github.com/CQCL/hugr/blob/main/DEVELOPMENT.md) for instructions on setting up the development environment.

## License

This project is licensed under Apache License, Version 2.0 ([LICENSE][] or http://www.apache.org/licenses/LICENSE-2.0).

[API documentation here]: https://docs.rs/hugr-core/
[build_status]: https://github.com/CQCL/hugr/actions/workflows/ci-rs.yml/badge.svg?branch=main
[msrv]: https://img.shields.io/badge/rust-1.75.0%2B-blue.svg
[crates]: https://img.shields.io/crates/v/hugr-core
[codecov]: https://img.shields.io/codecov/c/gh/CQCL/hugr?logo=codecov
[LICENSE]: https://github.com/CQCL/hugr/blob/main/LICENCE
[CHANGELOG]: https://github.com/CQCL/hugr/blob/main/hugr-core/CHANGELOG.md
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
//! ### Example
//!
//! ```yaml
#![doc = include_str!("../../examples/extension/declarative.yaml")]
#![doc = include_str!("../../../hugr/examples/extension/declarative.yaml")]
//! ```
//!
//! The definition can be loaded into a registry using the [`load_extensions`] or [`load_extensions_file`] functions.
//! ```rust
//! # const DECLARATIVE_YAML: &str = include_str!("../../examples/extension/declarative.yaml");
//! # const DECLARATIVE_YAML: &str = include_str!("../../../hugr/examples/extension/declarative.yaml");
//! # use hugr::extension::declarative::load_extensions;
//! // Required extensions must already be present in the registry.
//! let mut reg = hugr::std_extensions::logic::LOGIC_REG.clone();
Expand Down Expand Up @@ -327,7 +327,7 @@ extensions:
"#;

/// The yaml used in the module documentation.
const EXAMPLE_YAML_FILE: &str = "examples/extension/declarative.yaml";
const EXAMPLE_YAML_FILE: &str = "../hugr/examples/extension/declarative.yaml";

#[rstest]
#[case(EMPTY_YAML, 1, 0, 0, &PRELUDE_REGISTRY)]
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: hugr/src/hugr/views/tests.rs
source: hugr-core/src/hugr/views/tests.rs
expression: h.dot_string()
---
digraph {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: hugr/views/tests.rs
source: hugr-core/views/tests.rs
expression: h.dot_string()
---
digraph {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: hugr/src/hugr/views/tests.rs
source: hugr-core/src/hugr/views/tests.rs
expression: h.dot_string()
---
digraph {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: hugr/src/hugr/views/tests.rs
source: hugr-core/src/hugr/views/tests.rs
expression: h.mermaid_string()
---
graph LR
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: src/hugr/views/tests.rs
source: hugr-core/src/hugr/views/tests.rs
expression: h.mermaid_string()
---
graph LR
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: hugr/src/hugr/views/tests.rs
source: hugr-core/src/hugr/views/tests.rs
expression: h.mermaid_string()
---
graph LR
Expand Down
File renamed without changes.
31 changes: 31 additions & 0 deletions hugr-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//! Extensible, graph-based program representation with first-class support for linear types.
//!
//! This crate contains the core definitions for the HUGR representation.
//! See the [top-level crate documentation](https://docs.rs/hugr/latest/hugr/) for more information.
// proptest-derive generates many of these warnings.
// https://github.com/rust-lang/rust/issues/120363
// https://github.com/proptest-rs/proptest/issues/447
#![cfg_attr(test, allow(non_local_definitions))]

pub mod builder;
pub mod core;
pub mod extension;
pub mod hugr;
pub mod macros;
pub mod ops;
pub mod std_extensions;
pub mod types;
pub mod utils;

pub use crate::core::{
CircuitUnit, Direction, IncomingPort, Node, NodeIndex, OutgoingPort, Port, PortIndex, Wire,
};
pub use crate::extension::Extension;
pub use crate::hugr::{Hugr, HugrView, SimpleReplacement};

#[cfg(feature = "cli")]
pub mod cli;

#[cfg(test)]
pub mod proptest;
4 changes: 2 additions & 2 deletions hugr/src/macros.rs → hugr-core/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub(crate) use impl_box_clone;
///
/// Example:
/// ```
/// # use hugr::macros::type_row;
/// # use hugr::type_row;
/// # use hugr::types::{FunctionType, Type, TypeRow};
/// const U: Type = Type::UNIT;
/// let static_row: TypeRow = type_row![U, U];
Expand Down Expand Up @@ -86,7 +86,7 @@ pub use type_row;
/// of a test module only. Example:
/// ```rust
/// # mod test {
/// # use hugr::macros::const_extension_ids;
/// # use hugr::const_extension_ids;
/// const_extension_ids! {
/// pub const EXT_A: ExtensionId = "A";
/// /// A doc comment
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions hugr-passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ keywords = ["Quantum", "Quantinuum"]
categories = ["compilers"]

[dependencies]
hugr = { path = "../hugr", version = "0.4.0" }
hugr-core = { path = "../hugr-core", version = "0.0.0" }
itertools = { workspace = true }
lazy_static = { workspace = true }
paste = { workspace = true }
thiserror = { workspace = true }

[features]
extension_inference = ["hugr/extension_inference"]
extension_inference = ["hugr-core/extension_inference"]

[dev-dependencies]
rstest = "0.19.0"
8 changes: 4 additions & 4 deletions hugr-passes/src/const_fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use std::collections::{BTreeSet, HashMap};
use itertools::Itertools;
use thiserror::Error;

use hugr::hugr::{SimpleReplacementError, ValidationError};
use hugr::types::SumType;
use hugr::Direction;
use hugr::{
use hugr_core::hugr::{SimpleReplacementError, ValidationError};
use hugr_core::types::SumType;
use hugr_core::Direction;
use hugr_core::{
builder::{DFGBuilder, Dataflow, DataflowHugr},
extension::{ConstFoldResult, ExtensionRegistry},
hugr::{
Expand Down
36 changes: 18 additions & 18 deletions hugr-passes/src/const_fold/test.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
use crate::const_fold::constant_fold_pass;
use hugr::builder::{DFGBuilder, Dataflow, DataflowHugr};
use hugr::extension::prelude::{sum_with_error, ConstError, ConstString, BOOL_T, STRING_TYPE};
use hugr::extension::{ExtensionRegistry, PRELUDE};
use hugr::ops::Value;
use hugr::std_extensions::arithmetic;
use hugr::std_extensions::arithmetic::int_ops::IntOpDef;
use hugr::std_extensions::arithmetic::int_types::{ConstInt, INT_TYPES};
use hugr::std_extensions::logic::{self, NaryLogic, NotOp};
use hugr::type_row;
use hugr::types::{FunctionType, Type, TypeRow};
use hugr_core::builder::{DFGBuilder, Dataflow, DataflowHugr};
use hugr_core::extension::prelude::{sum_with_error, ConstError, ConstString, BOOL_T, STRING_TYPE};
use hugr_core::extension::{ExtensionRegistry, PRELUDE};
use hugr_core::ops::Value;
use hugr_core::std_extensions::arithmetic;
use hugr_core::std_extensions::arithmetic::int_ops::IntOpDef;
use hugr_core::std_extensions::arithmetic::int_types::{ConstInt, INT_TYPES};
use hugr_core::std_extensions::logic::{self, NaryLogic, NotOp};
use hugr_core::type_row;
use hugr_core::types::{FunctionType, Type, TypeRow};

use rstest::rstest;

use lazy_static::lazy_static;

use super::*;
use hugr::builder::Container;
use hugr::ops::{OpType, UnpackTuple};
use hugr::std_extensions::arithmetic::conversions::ConvertOpDef;
use hugr::std_extensions::arithmetic::float_ops::FloatOps;
use hugr::std_extensions::arithmetic::float_types::{ConstF64, FLOAT64_TYPE};
use hugr_core::builder::Container;
use hugr_core::ops::{OpType, UnpackTuple};
use hugr_core::std_extensions::arithmetic::conversions::ConvertOpDef;
use hugr_core::std_extensions::arithmetic::float_ops::FloatOps;
use hugr_core::std_extensions::arithmetic::float_types::{ConstF64, FLOAT64_TYPE};

/// Check that a hugr just loads and returns a single expected constant.
pub fn assert_fully_folded(h: &Hugr, expected_value: &Value) {
Expand Down Expand Up @@ -127,7 +127,7 @@ fn test_big() {
ignore = "inference fails for test graph, it shouldn't"
)]
fn test_list_ops() -> Result<(), Box<dyn std::error::Error>> {
use hugr::std_extensions::collections::{self, ListOp, ListValue};
use hugr_core::std_extensions::collections::{self, ListOp, ListValue};

let reg = ExtensionRegistry::try_new([
PRELUDE.to_owned(),
Expand Down Expand Up @@ -230,8 +230,8 @@ fn orphan_output() {
//
// We arange things so that the `or` folds away first, leaving the not
// with no outputs.
use hugr::hugr::NodeType;
use hugr::ops::handle::NodeHandle;
use hugr_core::hugr::NodeType;
use hugr_core::ops::handle::NodeHandle;

let mut build = DFGBuilder::new(FunctionType::new(type_row![], vec![BOOL_T])).unwrap();
let true_wire = build.add_load_value(Value::true_val());
Expand Down
14 changes: 7 additions & 7 deletions hugr-passes/src/half_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use std::hash::Hash;

use super::nest_cfgs::CfgNodeMap;

use hugr::hugr::RootTagged;
use hugr_core::hugr::RootTagged;

use hugr::ops::handle::CfgID;
use hugr::ops::{OpTag, OpTrait};
use hugr_core::ops::handle::CfgID;
use hugr_core::ops::{OpTag, OpTrait};

use hugr::{Direction, Node};
use hugr_core::{Direction, Node};

/// We provide a view of a cfg where every node has at most one of
/// (multiple predecessors, multiple successors).
Expand Down Expand Up @@ -97,9 +97,9 @@ impl<H: RootTagged<RootHandle = CfgID>> CfgNodeMap<HalfNode> for HalfNodeView<H>
mod test {
use super::super::nest_cfgs::{test::*, EdgeClassifier};
use super::{HalfNode, HalfNodeView};
use hugr::builder::BuildError;
use hugr::hugr::views::RootChecked;
use hugr::ops::handle::NodeHandle;
use hugr_core::builder::BuildError;
use hugr_core::hugr::views::RootChecked;
use hugr_core::ops::handle::NodeHandle;

use itertools::Itertools;
use std::collections::HashSet;
Expand Down
Loading

0 comments on commit bb1565f

Please sign in to comment.