Skip to content

Commit

Permalink
[Cider2] Pin signature vals and lookup by name (#2242)
Browse files Browse the repository at this point in the history
  • Loading branch information
EclecticGriffin committed Aug 1, 2024
1 parent 45d29cd commit 367370a
Show file tree
Hide file tree
Showing 6 changed files with 367 additions and 29 deletions.
12 changes: 1 addition & 11 deletions interp/src/debugger/debugging_context/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,7 @@ impl BreakPoint {
}

pub fn format(&self, ctx: &Context) -> String {
let parent_comp = ctx
.primary
.components
.keys()
.find(|comp_id| {
ctx.secondary[*comp_id]
.definitions
.groups()
.contains(self.group)
})
.unwrap();
let parent_comp = ctx.get_component_from_group(self.group);
let parent_name = ctx.lookup_name(parent_comp);

let group_name = ctx.lookup_name(self.group);
Expand Down
48 changes: 42 additions & 6 deletions interp/src/flatten/flat_ir/component.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::flatten::structures::{
index_trait::IndexRange, indexed_map::IndexedMap, sparse_map::SparseMap,
index_trait::{IndexRange, SignatureRange},
indexed_map::IndexedMap,
sparse_map::SparseMap,
};

use super::{control::structures::ControlIdx, prelude::*};
Expand Down Expand Up @@ -75,8 +77,12 @@ pub struct ComponentCore {
pub struct AuxillaryComponentInfo {
/// Name of the component.
pub name: Identifier,
/// The input/output signature of this component.
pub signature: IndexRange<LocalPortOffset>,
/// The input/output signature of this component. This could probably be
/// rolled into a single range, or specialized construct but this is
/// probably fine for now.
pub signature_in: SignatureRange,
pub signature_out: SignatureRange,

/// the definitions created by this component
pub definitions: DefinitionRanges,

Expand All @@ -100,7 +106,8 @@ impl AuxillaryComponentInfo {
pub fn new_with_name(id: Identifier) -> Self {
Self {
name: id,
signature: IndexRange::empty_interval(),
signature_in: SignatureRange::new(),
signature_out: SignatureRange::new(),
port_offset_map: Default::default(),
ref_port_offset_map: Default::default(),
cell_offset_map: Default::default(),
Expand Down Expand Up @@ -153,15 +160,44 @@ impl AuxillaryComponentInfo {
self.definitions.comb_groups = IndexRange::new(start, end)
}

pub fn inputs(&self) -> impl Iterator<Item = LocalPortOffset> + '_ {
self.signature_in.iter()
}

pub fn outputs(&self) -> impl Iterator<Item = LocalPortOffset> + '_ {
self.signature_out.iter()
}

pub fn signature(&self) -> IndexRange<LocalPortOffset> {
// can't quite use min here since None is less than any other value and
// I want the least non-None value
let beginning =
match (self.signature_in.first(), self.signature_out.first()) {
(Some(b), Some(e)) => Some(std::cmp::min(b, e)),
(Some(b), None) => Some(b),
(None, Some(e)) => Some(e),
_ => None,
};

let end =
std::cmp::max(self.signature_in.last(), self.signature_out.last());

match (beginning, end) {
(Some(b), Some(e)) => IndexRange::new(b, e),
(None, None) => IndexRange::empty_interval(),
_ => unreachable!(),
}
}

fn offset_sizes(&self, cell_ty: ContainmentType) -> IdxSkipSizes {
let (port, ref_port) = match cell_ty {
ContainmentType::Local => (
self.port_offset_map.count() - self.signature.size(),
self.port_offset_map.count() - self.signature().size(),
self.ref_port_offset_map.count(),
),
ContainmentType::Ref => (
self.port_offset_map.count(),
self.ref_port_offset_map.count() - self.signature.size(),
self.ref_port_offset_map.count() - self.signature().size(),
),
};

Expand Down
24 changes: 17 additions & 7 deletions interp/src/flatten/flat_ir/control/translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
},
structures::{
context::{Context, InterpretationContext, SecondaryContext},
index_trait::IndexRange,
index_trait::{IndexRange, SignatureRange},
},
},
};
Expand Down Expand Up @@ -369,19 +369,29 @@ fn compute_local_layout(

let mut layout = Layout::default();

// need this to set the appropriate signature range on the component
let sig_base = aux.port_offset_map.peek_next_index();
let mut sigs_input = SignatureRange::new();
let mut sigs_output = SignatureRange::new();

// first, handle the signature ports
for port in comp.signature.borrow().ports() {
// first, handle the input signature ports
for port in comp.signature.borrow().ports().into_iter() {
let local_offset =
insert_port(&mut ctx.secondary, aux, port, ContainmentType::Local);
match &port.borrow().direction {
cir::Direction::Input => {
sigs_output.append_item(*local_offset.as_local().unwrap());
}
cir::Direction::Output => {
sigs_input.append_item(*local_offset.as_local().unwrap());
}
_ => unreachable!("inout port in component signature"),
}

layout.port_map.insert(port.as_raw(), local_offset);
}

// update the aux info with the signature layout
aux.signature =
IndexRange::new(sig_base, aux.port_offset_map.peek_next_index());
aux.signature_in = sigs_input;
aux.signature_out = sigs_output;

// second the group holes
for group in &comp.groups {
Expand Down
15 changes: 14 additions & 1 deletion interp/src/flatten/structures/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,19 @@ impl Context {
.find(|x| self.resolve_id(self.primary[*x].name()) == name)
}

pub fn get_component_from_group(&self, group: GroupIdx) -> ComponentIdx {
self.primary
.components
.keys()
.find(|comp_id| {
self.secondary[*comp_id]
.definitions
.groups()
.contains(group)
})
.unwrap()
}

/// This is a wildly inefficient search, only used for debugging right now.
/// TODO Griffin: if relevant, replace with something more efficient.
pub(crate) fn find_parent_cell(
Expand All @@ -351,7 +364,7 @@ impl Context {
) -> ParentIdx {
match target {
PortRef::Local(l) => {
if self.secondary[comp].signature.contains(l) {
if self.secondary[comp].signature().contains(l) {
comp.into()
} else {
//I would not recommend looking at this code
Expand Down
91 changes: 87 additions & 4 deletions interp/src/flatten/structures/environment/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,32 @@ impl Debug for CellLedger {
}
}

#[derive(Debug, Clone)]
struct PinnedPorts {
port_vals_list: Vec<(GlobalPortIdx, Value)>,
}

impl PinnedPorts {
pub fn iter(&self) -> impl Iterator<Item = &(GlobalPortIdx, Value)> + '_ {
self.port_vals_list.iter()
}

pub fn new() -> Self {
Self {
port_vals_list: vec![],
}
}

pub fn push(&mut self, port: GlobalPortIdx, val: Value) {
// linear scan is probably fine here since the list should be relatively small
assert!(
!self.port_vals_list.iter().any(|x| x.0 == port),
"attempting to pin the same port twice"
);
self.port_vals_list.push((port, val));
}
}

#[derive(Debug)]
pub struct Environment<C: AsRef<Context> + Clone> {
/// A map from global port IDs to their current values.
Expand All @@ -238,6 +264,8 @@ pub struct Environment<C: AsRef<Context> + Clone> {
/// The program counter for the whole program execution.
pub(super) pc: ProgramCounter,

pinned_ports: PinnedPorts,

/// The immutable context. This is retained for ease of use.
/// This value should have a cheap clone implementation, such as &Context
/// or RC<Context>.
Expand Down Expand Up @@ -272,7 +300,7 @@ impl<C: AsRef<Context> + Clone> Environment<C> {
let comp_ledger = self.cells[cell].as_comp().unwrap();
let comp_info =
self.ctx().secondary.comp_aux_info.get(comp_ledger.comp_id);
let port_ids = comp_info.signature.into_iter().map(|x| {
let port_ids = comp_info.signature().into_iter().map(|x| {
&self.ctx().secondary.local_port_defs
[comp_info.port_offset_map[x]]
.name
Expand Down Expand Up @@ -324,6 +352,7 @@ impl<C: AsRef<Context> + Clone> Environment<C> {
pc: ProgramCounter::new_empty(),
ctx,
memory_header: None,
pinned_ports: PinnedPorts::new(),
};

let root_node = CellLedger::new_comp(root, &env);
Expand Down Expand Up @@ -386,7 +415,7 @@ impl<C: AsRef<Context> + Clone> Environment<C> {
}

// first layout the signature
for sig_port in comp_aux.signature.iter() {
for sig_port in comp_aux.signature().iter() {
let idx = self.ports.push(PortValue::new_undef());
debug_assert_eq!(index_bases + sig_port, idx);
}
Expand Down Expand Up @@ -860,7 +889,7 @@ impl<C: AsRef<Context> + Clone> Environment<C> {
// signature ports
if let Some(local) = target.as_port() {
let offset = local - &current_ledger.index_bases;
if current_info.signature.contains(offset) {
if current_info.signature().contains(offset) {
return Some((path, None));
}
}
Expand Down Expand Up @@ -1020,7 +1049,7 @@ impl<C: AsRef<Context> + Clone> Environment<C> {
} else {
let ledger = self.cells[cell].as_comp().unwrap();
let comp = &self.ctx.as_ref().secondary[ledger.comp_id];
Box::new(comp.signature.iter().map(|x| {
Box::new(comp.signature().into_iter().map(|x| {
let def_idx = comp.port_offset_map[x];
let def = &self.ctx.as_ref().secondary[def_idx];
(def.name, &ledger.index_bases + x)
Expand All @@ -1047,6 +1076,43 @@ impl<C: AsRef<Context> + Clone> Environment<C> {
},
)
}

/// Lookup the value of a port on the entrypoint component by name. Will
/// error if the port is not found.
pub fn lookup_port_from_string(&self, port: &String) -> Option<Value> {
// this is not the best way to do this but it's fine for now
let path = self.traverse_name_vec(&[port.to_string()]).unwrap();
let path_resolution = path.resolve_path(self).unwrap();
let idx = path_resolution.as_port().unwrap();

self.ports[*idx].as_option().map(|x| x.val().clone())
}

/// Pins the port with the given name to the given value. This may only be
/// used for input ports on the entrypoint component (excluding the go port)
/// and will panic if used otherwise. Intended for external use. Unrelated
/// to the rust pin.
pub fn pin_value<S: AsRef<str>>(&mut self, port: S, val: Value) {
let string = port.as_ref();

let root = Self::get_root();

let ledger = self.cells[root].as_comp().unwrap();
let mut def_list = self.ctx.as_ref().secondary[ledger.comp_id].inputs();
let found = def_list.find(|offset| {
let def_idx = self.ctx.as_ref().secondary[ledger.comp_id].port_offset_map[*offset];
self.ctx.as_ref().lookup_name(self.ctx.as_ref().secondary[def_idx].name) == string
}).expect("Could not find port with given name in the entrypoint component's input ports");

assert!(
found != self.ctx.as_ref().primary[ledger.comp_id].go,
"Cannot pin the go port"
);

let found = &ledger.index_bases + found;

self.pinned_ports.push(found, val);
}
}

/// A wrapper struct for the environment that provides the functions used to
Expand Down Expand Up @@ -1129,6 +1195,19 @@ impl<C: AsRef<Context> + Clone> Simulator<C> {
pub fn print_pc(&self) {
self.env.print_pc()
}

/// Pins the port with the given name to the given value. This may only be
/// used for input ports on the entrypoint component (excluding the go port)
/// and will panic if used otherwise. Intended for external use.
pub fn pin_value<S: AsRef<str>>(&mut self, port: S, val: Value) {
self.env.pin_value(port, val)
}

/// Lookup the value of a port on the entrypoint component by name. Will
/// error if the port is not found.
pub fn lookup_port_from_string(&self, port: &String) -> Option<Value> {
self.env.lookup_port_from_string(port)
}
}

// =========================== simulation functions ===========================
Expand Down Expand Up @@ -1364,6 +1443,10 @@ impl<C: AsRef<Context> + Clone> Simulator<C> {
pub fn converge(&mut self) -> InterpreterResult<()> {
self.undef_all_ports();
self.set_root_go_high();
// set the pinned values
for (port, val) in self.env.pinned_ports.iter() {
self.env.ports[*port] = PortValue::new_implicit(val.clone());
}

for comp in self.env.pc.finished_comps() {
let done_port = self.env.get_comp_done(*comp);
Expand Down
Loading

0 comments on commit 367370a

Please sign in to comment.