Skip to content

Commit 3264a9d

Browse files
committed
implement rewriting logic on ResourceScope
1 parent 91579fb commit 3264a9d

File tree

9 files changed

+768
-74
lines changed

9 files changed

+768
-74
lines changed

tket/src/resource.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use hugr::{
5757
};
5858
pub use interval::{Interval, InvalidInterval};
5959
use itertools::Itertools;
60-
pub use scope::{ResourceScope, ResourceScopeConfig};
60+
pub use scope::{CircuitRewriteError, ResourceScope, ResourceScopeConfig};
6161
pub use types::{CircuitUnit, Position, ResourceAllocator, ResourceId};
6262

6363
use crate::{
@@ -85,7 +85,8 @@ impl<H: HugrMut> ResourceScope<H> {
8585

8686
/// Register a rewrite applied to the circuit.
8787
///
88-
/// Returns `true` if the rewrite was successfully registered, or `false` if it was ignored.
88+
/// Returns `true` if the rewrite was successfully registered, or `false` if
89+
/// it was ignored.
8990
#[inline]
9091
pub fn add_rewrite_trace(&mut self, rewrite: impl Into<RewriteTrace>) -> bool {
9192
self.as_circuit_mut().add_rewrite_trace(rewrite)

tket/src/resource/scope.rs

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
//! tracking within a specific region of a HUGR, computing resource paths and
55
//! providing efficient lookup of circuit units associated with ports.
66
7+
mod patch;
8+
pub use patch::CircuitRewriteError;
9+
710
use std::{cmp, iter};
811

912
use crate::resource::flow::{DefaultResourceFlow, ResourceFlow};
@@ -165,17 +168,15 @@ impl<H: HugrView> ResourceScope<H> {
165168
self.hugr
166169
}
167170

168-
pub(crate) fn hugr_mut(&mut self) -> &mut H {
169-
&mut self.hugr
170-
}
171-
172171
/// Wrap the underlying HUGR in a Circuit as reference.
173172
pub fn as_circuit(&self) -> Circuit<&H> {
174173
Circuit::new(self.hugr())
175174
}
176175

177-
pub(crate) fn as_circuit_mut(&mut self) -> Circuit<&mut H> {
178-
Circuit::new(self.hugr_mut())
176+
/// Careful: this will not update the circuit units, so do not modify
177+
/// the HUGR using this.
178+
pub(super) fn as_circuit_mut(&mut self) -> Circuit<&mut H> {
179+
Circuit::new(&mut self.hugr)
179180
}
180181

181182
/// Get the underlying subgraph.
@@ -390,53 +391,37 @@ impl<H: HugrView> ResourceScope<H> {
390391
.flatten()
391392
.copied()
392393
.collect_vec();
393-
self.assign_circuit_units(all_inputs, &mut allocator);
394+
self.assign_missing_circuit_units(all_inputs, &mut allocator);
394395

395396
// Proceed to propagating the circuit units through the subgraph, in topological
396397
// order.
397398
for node in toposort_subgraph(&self.hugr, &self.subgraph, self.find_sources()) {
398-
if self.hugr.get_optype(node).dataflow_signature().is_none() {
399+
let Some(sig) = self.hugr.get_optype(node).dataflow_signature() else {
399400
// ignore non-dataflow ops
400401
continue;
401-
}
402-
self.assign_missing_circuit_units(node, &mut allocator);
402+
};
403+
404+
let incoming_ports = sig.input_ports().map(|p| (node, p));
405+
self.assign_missing_circuit_units(incoming_ports, &mut allocator);
403406
self.propagate_to_outputs(node, flows, &mut allocator);
404407
self.propagate_to_next_inputs(node);
405408
}
406409
}
407410

408-
/// Assign circuit units to the given ports in order.
409-
fn assign_circuit_units(
411+
/// Assign circuit units to the given ports in order, if they don't already
412+
/// have a circuit unit.
413+
fn assign_missing_circuit_units(
410414
&mut self,
411415
incoming_ports: impl IntoIterator<Item = (H::Node, IncomingPort)>,
412416
allocator: &mut CircuitUnitAllocator,
413417
) {
414418
for (node, port) in incoming_ports {
415-
let unit = allocator.allocate_circuit_unit(node, port, &self.hugr);
416419
let node_units = node_circuit_units_mut(&mut self.circuit_units, node, &self.hugr);
417-
node_units.port_map.set(port, unit);
418-
}
419-
}
420-
421-
/// Ensure all input ports of `node` have assigned circuit units.
422-
fn assign_missing_circuit_units(
423-
&mut self,
424-
node: H::Node,
425-
allocator: &mut CircuitUnitAllocator,
426-
) {
427-
let signature = self
428-
.hugr
429-
.get_optype(node)
430-
.dataflow_signature()
431-
.expect("dataflow op");
432-
433-
let mut incoming_ports = signature.input_ports().collect_vec();
434-
if let Some(node_units) = self.circuit_units.get(&node) {
435-
// Only assign circuit units to input ports without assigned units
436-
incoming_ports.retain(|&p| node_units.port_map.get(p).is_sentinel());
420+
if node_units.port_map.get(port).is_sentinel() {
421+
let unit = allocator.allocate_circuit_unit(node, port, &self.hugr);
422+
node_units.port_map.set(port, unit);
423+
}
437424
}
438-
439-
self.assign_circuit_units(incoming_ports.into_iter().map(|p| (node, p)), allocator);
440425
}
441426

442427
/// Find source nodes (nodes with no predecessors in the subgraph).

0 commit comments

Comments
 (0)