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::{BTreeMap, HashSet};
use std::fmt::{Error, Write};
use std::fs::File;
use std::io::BufWriter;
use std::iter::zip;
use std::mem::transmute;
use std::sync::atomic::{AtomicUsize, Ordering};
......@@ -105,7 +107,7 @@ where
}
// 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 {
Add,
Mult,
......@@ -138,7 +140,7 @@ where
* 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++.
*/
pub fn grape_codegen<Writer: Write>(
pub fn grape_codegen<Writer: std::fmt::Write>(
module_name: &str,
function: &Function,
types: &Vec<Type>,
......@@ -151,7 +153,7 @@ pub fn grape_codegen<Writer: Write>(
backing_allocation: &FunctionBackingAllocation,
w: &mut Writer,
) -> Result<(), Error> {
let ctx = GRAPEContext::<4, 4, 1> {
let ctx = GRAPEContext::<24, 24, 1> {
module_name,
function,
types,
......@@ -214,7 +216,7 @@ where
// while any node is not, and used slices is less than 4 < schedule live_outs.
let chip = self.schedule_slice(live_outs)?;
chip.0.pretty_print();
// chip.0.pretty_print();
// println!("chip: {:?}", chip);
let bitstream = Self::assemble_slice(chip.0);
......@@ -223,8 +225,17 @@ where
.iter()
.map(|&b| if b { '1' } else { '0' })
.collect();
println!("bitstream :{:?}", binary_string);
print_xdot(&chip.0);
// println!("bitstream :{:?}", binary_string);
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!();
// Assemble to bitstream.
......@@ -249,7 +260,7 @@ where
// Switchbox,
let mut bits_for_sb = sb.bits();
println!("bits_for_sb: {:?}", bits_for_sb);
// println!("bits_for_sb: {:?}", bits_for_sb);
// FU
let mut bits_for_fu = fu.bits();
......@@ -286,7 +297,7 @@ where
op_type: FuOp::Default,
}; W]; H];
let mut switchboxes = [[Switchbox {
output_wires: (0, 0),
output_wires: (100, 100),
}; W]; H - 1];
// let mut next_live_outs: [NodeID; W] = [NodeID::new(0); W];
......@@ -294,8 +305,58 @@ where
for row in (0..H).rev() {
println!("row: {:?}", row);
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 {
// 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.
let node = &self.function.nodes[live_out.idx()];
println!(
......@@ -307,7 +368,6 @@ where
.as_ref()
.iter()
.filter(|n| !self.function.nodes[n.idx()].is_control())
.chain(live_not_computed.iter())
.cloned()
.collect();
......@@ -319,11 +379,14 @@ where
let mut ctr = 0;
println!("uses: {:?}", uses);
// Try to schedule things live_outs uses.
for u in uses {
let users = self.def_use_map.get_users(u);
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.
let col = Self::get_free_col(&next_live_outs);
......@@ -335,10 +398,14 @@ where
"schedule already live value {:?} pass through @ {:?}",
u, col
);
idx_vec[ctr] = col;
if row != (H - 1) {
idx_vec[ctr] = col;
}
} else if next_live_outs.contains_key(&u) {
// reuse
idx_vec[ctr] = next_live_outs[&u];
if row != (H - 1) {
idx_vec[ctr] = next_live_outs[&u];
}
println!("reuse value {:?}", u);
} else if (u_node_data.is_constant()
|| u_node_data.is_dynamic_constant()
......@@ -351,7 +418,9 @@ where
op_type: FuOp::PassA,
};
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)) {
// Can't schedule this yet, schedule a passthrough instead
let col = Self::get_free_col(&next_live_outs);
......@@ -362,7 +431,9 @@ where
op_type: FuOp::PassA,
};
println!("schedule node {:?} pass through @ {:?}", u, col);
idx_vec[ctr] = col;
if row != (H - 1) {
idx_vec[ctr] = col;
}
} else {
// Schedule Computation
let col = Self::get_free_col(&next_live_outs);
......@@ -370,17 +441,21 @@ where
functional_units[row][col] = FunctionalUnit { op_type: FuOp::Add };
println!("schedule node {:?} computation @ {:?}", u, col);
idx_vec[ctr] = col;
if row != (H - 1) {
idx_vec[ctr] = col;
}
live_not_computed.remove(&u);
}
ctr += 1;
}
// Set switcboxes for newly scheduled inputs.
let a = idx_vec[0];
let b = idx_vec[1];
// maybe row + 1.
if row != (H - 1) {
let a = idx_vec[0];
let b = idx_vec[1];
// According to binop type
println!(
......@@ -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
[(); H - 1]:,
{
println!("XDOT:");
println!("digraph {{");
println!("node [shape=square]");
// writeln!(writer,"XDOT:");
writeln!(writer,"digraph {{");
writeln!(writer,"node [shape=square]");
for (row_num, row) in slice.functional_units.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 (col_num, sb) in row.iter().enumerate() {
println!(
"n_{}_{} -> n_{}_{}",
row_num,
sb.output_wires.0,
row_num + 1,
col_num
);
println!(
if sb.output_wires.0 != 100 {
writeln!(writer,
"n_{}_{} -> n_{}_{}",
row_num,
sb.output_wires.0,
row_num + 1,
col_num
);
}
if sb.output_wires.1 != 100 {
writeln!(writer,
"n_{}_{} -> n_{}_{}",
row_num,
sb.output_wires.1,
row_num + 1,
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 col_num in 0..row.len() {
print!("n_{}_{}", col_num, row_num);
......@@ -457,7 +541,7 @@ where
print!(" -> ");
}
}
println!("");
writeln!(writer,"");
}
for (row_num, row) in slice.functional_units.iter().enumerate() {
print!("rank=same {{");
......@@ -467,7 +551,7 @@ where
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] {
}
#[entry]
fn entry(a0, a1, a2, a3, a4, a5, a6, a7, k0, k1, k2 : i32) -> i32, i32, i32, i32, i32, i32, i32, i32 {
let a : i32[8];
fn entry(a0, a1, a2, a3, k0, k1, k2 : i32) -> i32, i32, i32, i32 {
let a : i32[4];
let k : i32[3];
a[0] = a0;
a[1] = a1;
a[2] = a2;
a[3] = a3;
a[4] = a4;
a[5] = a5;
a[6] = a6;
a[7] = a7;
k[0] = k0;
k[1] = k1;
k[2] = k2;
let r = conv1d::<8, 3>(a, k);
return r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7];
let r = conv1d::<4, 3>(a, k);
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