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

horrible horrible

parent 2b4dd87b
No related branches found
No related tags found
No related merge requests found
Pipeline #202301 failed
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, HashSet};
use std::fmt::{Error, Write}; use std::fmt::{Error, Write};
use std::fs::File;
use std::io::BufWriter;
use std::iter::zip; use std::iter::zip;
use std::mem::transmute; use std::mem::transmute;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
...@@ -105,7 +107,7 @@ where ...@@ -105,7 +107,7 @@ where
} }
// Operations that individual functional units support. Unary ops operate on the first input. // Operations that individual functional units support. Unary ops operate on the first input.
#[derive(Clone, Debug, Copy)] #[derive(Clone, Debug, Copy, PartialEq)]
pub enum FuOp { pub enum FuOp {
Add, Add,
Mult, Mult,
...@@ -138,7 +140,7 @@ where ...@@ -138,7 +140,7 @@ where
* execution on the CPU. We generate LLVM IR textually, since there are no good * execution on the CPU. We generate LLVM IR textually, since there are no good
* LLVM bindings for Rust, and we are *not* writing any C++. * LLVM bindings for Rust, and we are *not* writing any C++.
*/ */
pub fn grape_codegen<Writer: Write>( pub fn grape_codegen<Writer: std::fmt::Write>(
module_name: &str, module_name: &str,
function: &Function, function: &Function,
types: &Vec<Type>, types: &Vec<Type>,
...@@ -151,7 +153,7 @@ pub fn grape_codegen<Writer: Write>( ...@@ -151,7 +153,7 @@ pub fn grape_codegen<Writer: Write>(
backing_allocation: &FunctionBackingAllocation, backing_allocation: &FunctionBackingAllocation,
w: &mut Writer, w: &mut Writer,
) -> Result<(), Error> { ) -> Result<(), Error> {
let ctx = GRAPEContext::<4, 4, 1> { let ctx = GRAPEContext::<24, 24, 1> {
module_name, module_name,
function, function,
types, types,
...@@ -214,7 +216,7 @@ where ...@@ -214,7 +216,7 @@ where
// while any node is not, and used slices is less than 4 < schedule live_outs. // while any node is not, and used slices is less than 4 < schedule live_outs.
let chip = self.schedule_slice(live_outs)?; let chip = self.schedule_slice(live_outs)?;
chip.0.pretty_print(); // chip.0.pretty_print();
// println!("chip: {:?}", chip); // println!("chip: {:?}", chip);
let bitstream = Self::assemble_slice(chip.0); let bitstream = Self::assemble_slice(chip.0);
...@@ -223,8 +225,17 @@ where ...@@ -223,8 +225,17 @@ where
.iter() .iter()
.map(|&b| if b { '1' } else { '0' }) .map(|&b| if b { '1' } else { '0' })
.collect(); .collect();
println!("bitstream :{:?}", binary_string); // println!("bitstream :{:?}", binary_string);
print_xdot(&chip.0); let mut string = String::new();
let path = "results.txt";
let mut output = File::create(path).unwrap();
write_xdot(&chip.0, &mut string);
std::fs::write("results.txt", string);
// write!(output, "{}", string);
todo!(); todo!();
// Assemble to bitstream. // Assemble to bitstream.
...@@ -249,7 +260,7 @@ where ...@@ -249,7 +260,7 @@ where
// Switchbox, // Switchbox,
let mut bits_for_sb = sb.bits(); let mut bits_for_sb = sb.bits();
println!("bits_for_sb: {:?}", bits_for_sb); // println!("bits_for_sb: {:?}", bits_for_sb);
// FU // FU
let mut bits_for_fu = fu.bits(); let mut bits_for_fu = fu.bits();
...@@ -286,7 +297,7 @@ where ...@@ -286,7 +297,7 @@ where
op_type: FuOp::Default, op_type: FuOp::Default,
}; W]; H]; }; W]; H];
let mut switchboxes = [[Switchbox { let mut switchboxes = [[Switchbox {
output_wires: (0, 0), output_wires: (100, 100),
}; W]; H - 1]; }; W]; H - 1];
// let mut next_live_outs: [NodeID; W] = [NodeID::new(0); W]; // let mut next_live_outs: [NodeID; W] = [NodeID::new(0); W];
...@@ -294,8 +305,58 @@ where ...@@ -294,8 +305,58 @@ where
for row in (0..H).rev() { for row in (0..H).rev() {
println!("row: {:?}", row); println!("row: {:?}", row);
next_live_outs.clear(); next_live_outs.clear();
let mut blarghs: HashMap<NodeID, usize> = HashMap::new();
// Try to compute live not generated
for u in &live_not_computed.clone() {
println!("in live not computed node {:?}", u);
let mut users = self.def_use_map.get_users(*u).iter().filter(|node| !self.function.nodes[node.idx()].is_control());
let u_node_data = &self.function.nodes[u.idx()];
let mut col = 0;
if !users.all(|user| live_outs.contains_key(user)) {
// Can't schedule this yet, schedule a passthrough instead
col = Self::get_free_col(&next_live_outs);
next_live_outs.insert(*u, col);
blarghs.insert(*u, col);
live_not_computed.insert(*u);
// Schedule Pass Through
functional_units[row][col] = FunctionalUnit {
op_type: FuOp::PassA,
};
println!("schedule node {:?} pass through @ {:?}", u, col);
} else {
// Schedule Computation
col = Self::get_free_col(&next_live_outs);
next_live_outs.insert(*u, col);
blarghs.insert(*u, col);
functional_units[row][col] = FunctionalUnit { op_type: FuOp::Add };
println!("schedule node {:?} computation @ {:?}", u, col);
live_not_computed.remove(&u);
}
let live_out_col = live_outs[u];
switchboxes[row][live_out_col] = Switchbox {
output_wires: (col, col),
};
}
for (live_out, live_out_col) in &live_outs { for (live_out, live_out_col) in &live_outs {
// If this node is dead, don't schedule
if (live_not_computed.contains(live_out)) {
continue;
}
// If live outs, schedule as pass throughs to top. // If live outs, schedule as pass throughs to top.
let node = &self.function.nodes[live_out.idx()]; let node = &self.function.nodes[live_out.idx()];
println!( println!(
...@@ -307,7 +368,6 @@ where ...@@ -307,7 +368,6 @@ where
.as_ref() .as_ref()
.iter() .iter()
.filter(|n| !self.function.nodes[n.idx()].is_control()) .filter(|n| !self.function.nodes[n.idx()].is_control())
.chain(live_not_computed.iter())
.cloned() .cloned()
.collect(); .collect();
...@@ -319,11 +379,14 @@ where ...@@ -319,11 +379,14 @@ where
let mut ctr = 0; let mut ctr = 0;
println!("uses: {:?}", uses); println!("uses: {:?}", uses);
// Try to schedule things live_outs uses.
for u in uses { for u in uses {
let users = self.def_use_map.get_users(u); let users = self.def_use_map.get_users(u);
let u_node_data = &self.function.nodes[u.idx()]; let u_node_data = &self.function.nodes[u.idx()];
if live_outs.contains_key(&u) { if live_outs.contains_key(&u) && !blarghs.contains_key(&u){
// Keep it live. // Keep it live.
let col = Self::get_free_col(&next_live_outs); let col = Self::get_free_col(&next_live_outs);
...@@ -335,10 +398,14 @@ where ...@@ -335,10 +398,14 @@ where
"schedule already live value {:?} pass through @ {:?}", "schedule already live value {:?} pass through @ {:?}",
u, col u, col
); );
idx_vec[ctr] = col; if row != (H - 1) {
idx_vec[ctr] = col;
}
} else if next_live_outs.contains_key(&u) { } else if next_live_outs.contains_key(&u) {
// reuse // reuse
idx_vec[ctr] = next_live_outs[&u]; if row != (H - 1) {
idx_vec[ctr] = next_live_outs[&u];
}
println!("reuse value {:?}", u); println!("reuse value {:?}", u);
} else if (u_node_data.is_constant() } else if (u_node_data.is_constant()
|| u_node_data.is_dynamic_constant() || u_node_data.is_dynamic_constant()
...@@ -351,7 +418,9 @@ where ...@@ -351,7 +418,9 @@ where
op_type: FuOp::PassA, op_type: FuOp::PassA,
}; };
println!("schedule parameter {:?} pass through @ {:?}", u, col); println!("schedule parameter {:?} pass through @ {:?}", u, col);
idx_vec[ctr] = col; if row != (H - 1) {
idx_vec[ctr] = col;
}
} else if !users.iter().all(|user| live_outs.contains_key(user)) { } else if !users.iter().all(|user| live_outs.contains_key(user)) {
// Can't schedule this yet, schedule a passthrough instead // Can't schedule this yet, schedule a passthrough instead
let col = Self::get_free_col(&next_live_outs); let col = Self::get_free_col(&next_live_outs);
...@@ -362,7 +431,9 @@ where ...@@ -362,7 +431,9 @@ where
op_type: FuOp::PassA, op_type: FuOp::PassA,
}; };
println!("schedule node {:?} pass through @ {:?}", u, col); println!("schedule node {:?} pass through @ {:?}", u, col);
idx_vec[ctr] = col; if row != (H - 1) {
idx_vec[ctr] = col;
}
} else { } else {
// Schedule Computation // Schedule Computation
let col = Self::get_free_col(&next_live_outs); let col = Self::get_free_col(&next_live_outs);
...@@ -370,17 +441,21 @@ where ...@@ -370,17 +441,21 @@ where
functional_units[row][col] = FunctionalUnit { op_type: FuOp::Add }; functional_units[row][col] = FunctionalUnit { op_type: FuOp::Add };
println!("schedule node {:?} computation @ {:?}", u, col); println!("schedule node {:?} computation @ {:?}", u, col);
idx_vec[ctr] = col; if row != (H - 1) {
idx_vec[ctr] = col;
}
live_not_computed.remove(&u); live_not_computed.remove(&u);
} }
ctr += 1; ctr += 1;
} }
// Set switcboxes for newly scheduled inputs. // Set switcboxes for newly scheduled inputs.
let a = idx_vec[0];
let b = idx_vec[1];
// maybe row + 1. // maybe row + 1.
if row != (H - 1) { if row != (H - 1) {
let a = idx_vec[0];
let b = idx_vec[1];
// According to binop type // According to binop type
println!( println!(
...@@ -417,39 +492,48 @@ where ...@@ -417,39 +492,48 @@ where
} }
} }
fn print_xdot<const H: usize, const W: usize>(slice: &SliceDesc<H, W>)
fn write_xdot<const H: usize, const W: usize, T: Write>(slice: &SliceDesc<H, W>, writer: &mut T)
where where
[(); H - 1]:, [(); H - 1]:,
{ {
println!("XDOT:"); // writeln!(writer,"XDOT:");
println!("digraph {{"); writeln!(writer,"digraph {{");
println!("node [shape=square]"); writeln!(writer,"node [shape=square]");
for (row_num, row) in slice.functional_units.iter().enumerate() { for (row_num, row) in slice.functional_units.iter().enumerate() {
for (col_num, fu) in row.iter().enumerate() { for (col_num, fu) in row.iter().enumerate() {
println!("n_{}_{} [label=\"{:?}\"]", row_num, col_num, fu.op_type); if fu.op_type != FuOp::Default {
writeln!(writer,"n_{}_{} [label=\"{:?}\"]", row_num, col_num, fu.op_type);
}
} }
} }
for (row_num, row) in slice.switchboxes.iter().enumerate() { for (row_num, row) in slice.switchboxes.iter().enumerate() {
for (col_num, sb) in row.iter().enumerate() { for (col_num, sb) in row.iter().enumerate() {
println!( if sb.output_wires.0 != 100 {
"n_{}_{} -> n_{}_{}", writeln!(writer,
row_num, "n_{}_{} -> n_{}_{}",
sb.output_wires.0, row_num,
row_num + 1, sb.output_wires.0,
col_num row_num + 1,
); col_num
println!( );
}
if sb.output_wires.1 != 100 {
writeln!(writer,
"n_{}_{} -> n_{}_{}", "n_{}_{} -> n_{}_{}",
row_num, row_num,
sb.output_wires.1, sb.output_wires.1,
row_num + 1, row_num + 1,
col_num col_num
); );
}
} }
} }
println!("edge [weight=1000 style=invis]"); writeln!(writer,"edge [weight=1000 style=invis]");
for (row_num, row) in slice.functional_units.iter().enumerate() { for (row_num, row) in slice.functional_units.iter().enumerate() {
for col_num in 0..row.len() { for col_num in 0..row.len() {
print!("n_{}_{}", col_num, row_num); print!("n_{}_{}", col_num, row_num);
...@@ -457,7 +541,7 @@ where ...@@ -457,7 +541,7 @@ where
print!(" -> "); print!(" -> ");
} }
} }
println!(""); writeln!(writer,"");
} }
for (row_num, row) in slice.functional_units.iter().enumerate() { for (row_num, row) in slice.functional_units.iter().enumerate() {
print!("rank=same {{"); print!("rank=same {{");
...@@ -467,7 +551,7 @@ where ...@@ -467,7 +551,7 @@ where
print!(" -> "); print!(" -> ");
} }
} }
println!("}}"); writeln!(writer,"}}");
} }
println!("}}"); writeln!(writer,"}}");
} }
...@@ -22,20 +22,16 @@ fn conv1d<n: usize, k: usize>(a : i32[n], kernel: i32[k]) -> i32[n] { ...@@ -22,20 +22,16 @@ fn conv1d<n: usize, k: usize>(a : i32[n], kernel: i32[k]) -> i32[n] {
} }
#[entry] #[entry]
fn entry(a0, a1, a2, a3, a4, a5, a6, a7, k0, k1, k2 : i32) -> i32, i32, i32, i32, i32, i32, i32, i32 { fn entry(a0, a1, a2, a3, k0, k1, k2 : i32) -> i32, i32, i32, i32 {
let a : i32[8]; let a : i32[4];
let k : i32[3]; let k : i32[3];
a[0] = a0; a[0] = a0;
a[1] = a1; a[1] = a1;
a[2] = a2; a[2] = a2;
a[3] = a3; a[3] = a3;
a[4] = a4;
a[5] = a5;
a[6] = a6;
a[7] = a7;
k[0] = k0; k[0] = k0;
k[1] = k1; k[1] = k1;
k[2] = k2; k[2] = k2;
let r = conv1d::<8, 3>(a, k); let r = conv1d::<4, 3>(a, k);
return r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]; return r[0], r[1], r[2], r[3];
} }
\ 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