Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 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
10 changes: 5 additions & 5 deletions tket-py/src/rewrite.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! PyO3 wrapper for rewriters.

use derive_more::From;
use hugr::HugrView;
use hugr::{hugr::views::SiblingSubgraph, HugrView};
use itertools::Itertools;
use pyo3::prelude::*;
use std::path::PathBuf;
use tket::{
rewrite::{CircuitRewrite, ECCRewriter, Rewriter, Subcircuit},
rewrite::{CircuitRewrite, ECCRewriter, Rewriter},
Circuit,
};

Expand Down Expand Up @@ -59,7 +59,7 @@ impl PyCircuitRewrite {
Ok(Self {
rewrite: CircuitRewrite::try_new(
&source_position.0,
&source_circ.circ,
source_circ.circ.hugr(),
replacement.circ,
)
.map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?,
Expand Down Expand Up @@ -103,15 +103,15 @@ impl Rewriter for PyRewriter {
#[pyo3(name = "Subcircuit")]
#[derive(Debug, Clone, From)]
#[repr(transparent)]
pub struct PySubcircuit(Subcircuit);
pub struct PySubcircuit(SiblingSubgraph);

#[pymethods]
impl PySubcircuit {
#[new]
fn from_nodes(nodes: Vec<PyNode>, circ: &Tk2Circuit) -> PyResult<Self> {
let nodes: Vec<_> = nodes.into_iter().map_into().collect();
Ok(Self(
Subcircuit::try_from_nodes(nodes, &circ.circ)
SiblingSubgraph::try_from_nodes(nodes, circ.circ.hugr())
.map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?,
))
}
Expand Down
33 changes: 19 additions & 14 deletions tket/src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ lazy_static! {
set
};
}
/// The [IGNORED_EXTENSION_OPS] definition depends on the buggy behaviour of [`NamedOp::name`], which returns bare names instead of scoped names on some cases.
/// Once this test starts failing it should be time to drop the `format!("prelude.{}", ...)`.
/// https://github.com/CQCL/hugr/issues/1496
/// The [IGNORED_EXTENSION_OPS] definition depends on the buggy behaviour of
/// [`NamedOp::name`], which returns bare names instead of scoped names on some
/// cases. Once this test starts failing it should be time to drop the
/// `format!("prelude.{}", ...)`. https://github.com/CQCL/hugr/issues/1496
#[test]
fn issue_1496_remains() {
assert_eq!("Noop", NoopDef.opdef_id())
Expand Down Expand Up @@ -134,8 +135,8 @@ impl<T: HugrView> Circuit<T> {
/// If the circuit is a function definition, returns the name of the
/// function.
///
/// If the name is empty or the circuit is not a function definition, returns
/// `None`.
/// If the name is empty or the circuit is not a function definition,
/// returns `None`.
#[inline]
pub fn name(&self) -> Option<&str> {
let op = self.hugr.get_optype(self.parent());
Expand Down Expand Up @@ -269,12 +270,14 @@ impl<T: HugrView> Circuit<T> {
.sum()
}

/// Return the graphviz representation of the underlying graph and hierarchy side by side.
/// Return the graphviz representation of the underlying graph and hierarchy
/// side by side.
///
/// For a simpler representation, use the [`Circuit::mermaid_string`] format instead.
/// For a simpler representation, use the [`Circuit::mermaid_string`] format
/// instead.
pub fn dot_string(&self) -> String {
// TODO: This will print the whole HUGR without identifying the circuit container.
// Should we add some extra formatting for that?
// TODO: This will print the whole HUGR without identifying the circuit
// container. Should we add some extra formatting for that?
self.hugr.dot_string()
}

Expand Down Expand Up @@ -333,12 +336,14 @@ impl<T: HugrView<Node = Node>> Circuit<T> {
})
}

/// Extracts the circuit into a new owned HUGR containing the circuit at the root.
/// Replaces the circuit container operation with an [`OpType::DFG`].
/// Extracts the circuit into a new owned HUGR containing the circuit at the
/// root. Replaces the circuit container operation with an
/// [`OpType::DFG`].
///
/// Regions that are not descendants of the parent node are not included in the new HUGR.
/// This may invalidate calls to functions defined elsewhere. Make sure to inline any
/// external functions before calling this method.
/// Regions that are not descendants of the parent node are not included in
/// the new HUGR. This may invalidate calls to functions defined
/// elsewhere. Make sure to inline any external functions before calling
/// this method.
pub fn extract_dfg(&self) -> Result<Circuit<Hugr>, CircuitMutError> {
let circ = self.to_owned();
// TODO: Can we just ignore this now?
Expand Down
1 change: 1 addition & 0 deletions tket/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ pub use circuit::{Circuit, CircuitError, CircuitMutError};
pub use hugr;
pub use hugr::Hugr;
pub use ops::{op_matches, symbolic_constant_op, Pauli, TketOp};
pub use subcircuit::Subcircuit;
15 changes: 8 additions & 7 deletions tket/src/passes/tuple_unpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use core::panic;
use hugr::builder::{DFGBuilder, Dataflow, DataflowHugr};
use hugr::extension::prelude::{MakeTuple, TupleOpDef};
use hugr::extension::simple_op::MakeExtensionOp;
use hugr::hugr::views::SiblingSubgraph;
use hugr::ops::{OpTrait, OpType};
use hugr::types::Type;
use hugr::{HugrView, Node};
use itertools::Itertools;

use crate::circuit::Command;
use crate::rewrite::{CircuitRewrite, Subcircuit};
use crate::rewrite::CircuitRewrite;
use crate::Circuit;

/// Find tuple pack operations followed by tuple unpack operations
Expand Down Expand Up @@ -102,8 +103,8 @@ fn remove_pack_unpack<T: HugrView<Node = Node>>(

let mut nodes = unpack_nodes;
nodes.push(pack_node);
let subcirc = Subcircuit::try_from_nodes(nodes, circ).unwrap();
let subcirc_signature = subcirc.signature(circ);
let subgraph = SiblingSubgraph::try_from_nodes(nodes, circ.hugr()).expect("is convex");
let subcirc_signature = subgraph.signature(circ.hugr());

// The output port order in `Subcircuit::try_from_nodes` is not too well defined.
// Check that the outputs are in the expected order.
Expand Down Expand Up @@ -142,14 +143,14 @@ fn remove_pack_unpack<T: HugrView<Node = Node>>(
.finish_hugr_with_outputs(outputs)
.unwrap_or_else(|e| {
panic!("Failed to create replacement for removing tuple pack/unpack operations. {e}")
})
.into();
});

subcirc
.create_rewrite(circ, replacement)
subgraph
.create_simple_replacement(circ.hugr(), replacement)
.unwrap_or_else(|e| {
panic!("Failed to create rewrite for removing tuple pack/unpack operations. {e}")
})
.into()
}

#[cfg(test)]
Expand Down
20 changes: 9 additions & 11 deletions tket/src/portmatching/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ use portmatching::{
};
use smol_str::SmolStr;

use crate::{
circuit::Circuit,
rewrite::{CircuitRewrite, Subcircuit},
};
use crate::{circuit::Circuit, rewrite::CircuitRewrite};

/// Matchable operations in a circuit.
#[derive(
Expand Down Expand Up @@ -75,7 +72,8 @@ fn encode_op(op: OpType) -> Option<Vec<u8>> {
/// pattern from the matcher.
#[derive(Clone)]
pub struct PatternMatch {
position: Subcircuit,
/// The matched subgraph.
subgraph: SiblingSubgraph,
pattern: PatternID,
/// The root of the pattern in the circuit.
///
Expand All @@ -96,13 +94,13 @@ impl PatternMatch {
}

/// Returns the matched subcircuit in the original circuit.
pub fn subcircuit(&self) -> &Subcircuit {
&self.position
pub fn subgraph(&self) -> &SiblingSubgraph {
&self.subgraph
}

/// Returns the matched nodes in the original circuit.
pub fn nodes(&self) -> &[Node] {
self.position.nodes()
self.subgraph.nodes()
}

/// Create a pattern match from the image of a pattern root.
Expand Down Expand Up @@ -205,7 +203,7 @@ impl PatternMatch {
let subgraph =
SiblingSubgraph::try_new_with_checker(inputs, outputs, circ.hugr(), checker)?;
Ok(Self {
position: subgraph.into(),
subgraph,
pattern,
root,
})
Expand All @@ -217,15 +215,15 @@ impl PatternMatch {
source: &Circuit<impl HugrView<Node = Node>>,
target: Circuit,
) -> Result<CircuitRewrite, InvalidReplacement> {
CircuitRewrite::try_new(&self.position, source, target)
CircuitRewrite::try_new(&self.subgraph, source.hugr(), target)
}
}

impl Debug for PatternMatch {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PatternMatch")
.field("root", &self.root)
.field("nodes", &self.position.subgraph.nodes())
.field("nodes", &self.subgraph.nodes())
.finish()
}
}
Expand Down
13 changes: 5 additions & 8 deletions tket/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

// Public API exports
pub use flow::{DefaultResourceFlow, ResourceFlow, UnsupportedOp};
pub use scope::{ResourceScope, ResourceScopeConfig};
pub use scope::ResourceScope;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there good reason to drop this public export?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, feel free to leave it :)

pub use types::{CircuitUnit, Position, ResourceAllocator, ResourceId};

// Internal modules
Expand All @@ -58,8 +58,6 @@ pub(crate) mod tests {
use hugr::{
builder::{DFGBuilder, Dataflow, DataflowHugr},
extension::prelude::qb_t,
hugr::views::SiblingSubgraph,
ops::handle::DataflowParentID,
types::Signature,
CircuitUnit, Hugr,
};
Expand All @@ -71,7 +69,7 @@ pub(crate) mod tests {
extension::rotation::{rotation_type, ConstRotation},
resource::scope::tests::ResourceScopeReport,
utils::build_simple_circuit,
TketOp,
Circuit, TketOp,
};

use super::ResourceScope;
Expand All @@ -89,7 +87,7 @@ pub(crate) mod tests {
}

// Gate being commuted has a non-linear input
fn circ(n_qubits: usize, add_rz: bool, add_const_rz: bool) -> Hugr {
pub fn cx_rz_circuit(n_qubits: usize, add_rz: bool, add_const_rz: bool) -> Hugr {
let build = || {
let out_qb_row = vec![qb_t(); n_qubits];
let mut inp_qb_row = out_qb_row.clone();
Expand Down Expand Up @@ -154,9 +152,8 @@ pub(crate) mod tests {
#[case] add_rz: bool,
#[case] add_const_rz: bool,
) {
let circ = circ(n_qubits, add_rz, add_const_rz);
let subgraph =
SiblingSubgraph::try_new_dataflow_subgraph::<_, DataflowParentID>(&circ).unwrap();
let circ = cx_rz_circuit(n_qubits, add_rz, add_const_rz);
let subgraph = Circuit::from(&circ).subgraph().unwrap();
let scope = ResourceScope::new(&circ, subgraph);
let info = ResourceScopeReport::from(&scope);

Expand Down
Loading
Loading