Skip to content
Snippets Groups Projects
Commit 8b9bbf6e authored by Xavier Routh's avatar Xavier Routh
Browse files

what the freak

parent 9d7e6d59
No related branches found
No related tags found
No related merge requests found
Pipeline #202271 failed
......@@ -75,7 +75,7 @@ pub fn grape_codegen<Writer: Write>(
types: &Vec<Type>,
constants: &Vec<Constant>,
dynamic_constants: &Vec<DynamicConstant>,
def_use_map: ImmutableDefUseMap,
def_use_map: &ImmutableDefUseMap,
typing: &Vec<TypeID>,
control_subgraph: &Subgraph,
bbs: &BasicBlocks,
......@@ -103,7 +103,7 @@ struct GRAPEContext<'a, const H: usize, const W: usize, const K:usize> {
types: &'a Vec<Type>,
constants: &'a Vec<Constant>,
dynamic_constants: &'a Vec<DynamicConstant>,
def_use_map: ImmutableDefUseMap,
def_use_map: &'a ImmutableDefUseMap,
typing: &'a Vec<TypeID>,
control_subgraph: &'a Subgraph,
bbs: &'a BasicBlocks,
......@@ -127,66 +127,89 @@ where [(); H -1]:
assert_eq!(set.len(), 2); // Because start and return are in different BBs.
let mut live_ins = HashMap::new();
let mut live_outs = HashMap::new();
for (idx, (node_id, node)) in self.function.nodes.iter().enumerate().filter(|(node_id, node)| node.is_parameter() || node.is_constant() || node.is_dynamic_constant()).enumerate() {
live_ins.insert(NodeID::new(node_id), idx);
for (idx, (node_id, node)) in self.function.nodes.iter().enumerate().filter(|(node_id, node)| node.is_return()).enumerate() {
live_outs.insert(NodeID::new(node_id), idx);
}
// Schedule the function,
let chip = self.schedule_slice(&live_ins)?;
// while any node is not, and used slices is less than 4 < schedule live_outs.
let chip = self.schedule_slice(live_outs)?;
println!("chip: {:?}", chip);
todo!();
// Assemble to bitstream.
Ok(())
}
fn schedule_slice(&self, live_ins: &HashMap<NodeID, usize>) -> Result<SliceDesc<H, W, K>, Error> {
fn schedule_slice(&self, mut live_outs: HashMap<NodeID, usize>) -> Result<(SliceDesc<H, W>, HashMap<NodeID, usize>), Error> {
let mut next_live_outs: HashMap<NodeID, usize> = HashMap::new(); // Node to the col they are live in.
let mut live_not_computed: HashSet<NodeID> = HashSet::new();
let mut live_ins: [NodeID; W] = [NodeID::new(0); W]; // Node to the col they are live in.
let mut next_live_ins: [NodeID; W] = [NodeID::new(0); W];
// Assign to first row.
let mut functional_units = [[FunctionalUnit { op_type: FuOp::Add} ; W]; H];
let mut switchboxes = [[Switchbox { output_wires: (0, 0)} ; W]; H - 1];
for row in 0..H {
let users = live_ins.iter().enumerate().flat_map(|(_, id)| self.def_use_map.get_users(*id));
// let mut next_live_outs: [NodeID; W] = [NodeID::new(0); W];
// Assign to last row
for row in (0..H).rev() {
live_outs.clear();
for user in users {
let uses = get_uses(&self.function.nodes[user.idx()]).as_ref();
// Check if all uses are live
if !uses.iter().all(|u| live_ins.iter().find(|id| *id == u).is_some()) {
continue;
for (live_out, live_out_col) in &live_outs {
// If live outs, schedule as pass throughs to top.
let node = &self.function.nodes[live_out.idx()];
if (node.is_constant() || node.is_dynamic_constant() || node.is_parameter()) && !live_not_computed.contains(live_out) {
let col = next_live_outs.len();
next_live_outs.insert(*live_out, col);
// Schedule Pass Through
functional_units[row][col] = FunctionalUnit { op_type: FuOp::PassA };
}
// All uses are live, we can schedule this.
let uses: Vec<NodeID> = get_uses(&self.function.nodes[live_out.idx()]).as_ref().iter().chain(live_not_computed.iter()).cloned().collect();
for u in uses {
live_ins[];
let users = self.def_use_map.get_users(u);
if !users.iter().all(|user| live_outs.contains_key(user)) {
// Can't schedule this yet, schedule a passthrough instead
let col = next_live_outs.len();
next_live_outs.insert(u, col);
live_not_computed.insert(u);
// Schedule Pass Through
functional_units[row][col] = FunctionalUnit { op_type: FuOp::PassA };
} else {
// Schedule Computation
let col = next_live_outs.len();
next_live_outs.insert(u, col);
functional_units[row][col] = FunctionalUnit {
op_type: FuOp::Add,
};
live_not_computed.remove(&u);
}
}
}
// For each node, if all users are live, then kill it.
for (node_id, col) in &live_ins {
let uses_vec: Vec<NodeID> = get_uses(&self.function.nodes[live_out.idx()]).as_ref().iter().cloned().collect();
// Set switcboxes for newly scheduled inputs.
let a = next_live_outs[&uses_vec[0]];
let b = next_live_outs[&uses_vec[1]];
// maybe row + 1.
switchboxes[row][*live_out_col] = Switchbox { output_wires: (a, b) };
}
// next_live_ins
// Set live values to pass through.
live_outs = next_live_outs.clone();
}
todo!()
Ok((SliceDesc::<H, W> { functional_units, switchboxes }, live_outs))
}
fn schedule_node(&self, map: &mut HashMap<NodeID, (usize, usize)>, node: NodeID, col: ) {
}
/*
* Lower data nodes in Hercules IR into LLVM instructions.
......
......@@ -6,14 +6,3 @@ fn grape_kernel(a: i32, b: i32) -> i32 {
fn entry() -> i32 {
return grape_kernel(2, 5);
}
ffft(a: [8; i32]) -> [8; i32] {
let b: [8;i32];
for (int i = 0; i < 8; i++) {
b[i] = a[i];
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment