slightly better at recursive partitioning

still very fucked
This commit is contained in:
SpaceCat-Chan 2022-12-11 00:10:43 +01:00 committed by Lofty
parent b38215062e
commit 000ad6d539
2 changed files with 103 additions and 50 deletions

View File

@ -182,9 +182,11 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
let dst_name = ctx.name_of_wire(arc.sink_wire()).to_str().unwrap();
if src_name.contains("FCO_SLICE")
|| src_name.contains("Q6_SLICE")
|| src_name.contains('J')
|| src_name.contains("DDR")
|| dst_name.contains("DDR")
|| dst_name.contains("X126/Y20/PADDOD_PIO")
{
special_arcs.push(arc);
} else {
@ -206,30 +208,21 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
for _ in 0..2 {
let mut new_partitions = Vec::with_capacity(partitions.len() * 4);
for (min, max, partition, name) in &partitions {
log_info!("partition {}:\n", name);
let (x_part, y_part, ne, se, sw, nw) = partition::find_partition_point_and_sanity_check(
ctx, &nets, partition, pips, min.x, max.x, min.y, max.y,
);
new_partitions.push((*min, Coord::new(x_part, y_part), ne, format!("{}_NE", name)));
new_partitions.push((
*min,
Coord::new(x_part + 1, y_part + 1),
ne,
format!("{}_NE", name),
));
new_partitions.push((
Coord::new(x_part - 1, min.y),
Coord::new(max.x, y_part + 1),
Coord::new(x_part, min.y),
Coord::new(max.x, y_part),
se,
format!("{}_SE", name),
));
new_partitions.push((Coord::new(x_part, y_part), *max, sw, format!("{}_SW", name)));
new_partitions.push((
Coord::new(x_part - 1, y_part - 1),
*max,
sw,
format!("{}_SW", name),
));
new_partitions.push((
Coord::new(min.x, y_part - 1),
Coord::new(x_part + 1, max.y),
Coord::new(min.x, y_part),
Coord::new(x_part, max.y),
nw,
format!("{}_NW", name),
));

View File

@ -155,12 +155,12 @@ impl Coord {
) -> Self {
match direction {
Direction::North => Coord {
x: self.x.clamp(min_bounds.x + 1, partition_point.x - 1),
x: self.x.clamp(min_bounds.x, partition_point.x - 1),
y: self.y,
},
Direction::East => Coord {
x: self.x,
y: self.y.clamp(min_bounds.y + 1, partition_point.y - 1),
y: self.y.clamp(min_bounds.y, partition_point.y - 1),
},
Direction::South => Coord {
x: self.x.clamp(partition_point.x + 1, max_bounds.x - 1),
@ -204,8 +204,8 @@ pub fn find_partition_point(
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
let mut x = ((x_finish - x_start) / 2) + x_start;
let mut y = ((y_finish - y_start) / 2) + y_start;
let mut x_diff = (x_finish - x_start) / 4;
let mut y_diff = (y_finish - y_start) / 4;
let mut x_diff = 0; //(x_finish - x_start) / 4;
let mut y_diff = 0; //(y_finish - y_start) / 4;
while x_diff != 0 {
let (ne, se, sw, nw) = approximate_partition_results(arcs, (x, y));
@ -863,6 +863,7 @@ pub fn find_partition_point_and_sanity_check(
let mut out_of_bound_arcs_in_sw = 0;
let mut out_of_bound_arcs_in_nw = 0;
println!("\nne:");
for arc in &ne {
if arc.source_loc().x > x_part
|| arc.source_loc().y > y_part
@ -876,9 +877,11 @@ pub fn find_partition_point_and_sanity_check(
|| arc.sink_loc().x <= x_start
|| arc.sink_loc().y <= y_start
{
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
out_of_bound_arcs_in_ne += 1;
}
}
println!("\nse:");
for arc in &se {
if arc.source_loc().x < x_part
|| arc.source_loc().y > y_part
@ -892,9 +895,11 @@ pub fn find_partition_point_and_sanity_check(
|| arc.sink_loc().x >= x_finish
|| arc.sink_loc().y <= y_start
{
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
out_of_bound_arcs_in_se += 1;
}
}
println!("\nsw:");
for arc in &sw {
if arc.source_loc().x < x_part
|| arc.source_loc().y < y_part
@ -908,9 +913,11 @@ pub fn find_partition_point_and_sanity_check(
|| arc.sink_loc().x >= x_finish
|| arc.sink_loc().y >= y_finish
{
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
out_of_bound_arcs_in_sw += 1;
}
}
println!("\nnw:");
for arc in &nw {
if arc.source_loc().x > x_part
|| arc.source_loc().y < y_part
@ -924,6 +931,7 @@ pub fn find_partition_point_and_sanity_check(
|| arc.sink_loc().x <= x_start
|| arc.sink_loc().y >= y_finish
{
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
out_of_bound_arcs_in_nw += 1;
}
}
@ -1019,8 +1027,8 @@ impl PipSelector {
for &pip in pips {
let loc = ctx.pip_location(pip);
if (loc.x == partition_point.x || loc.y == partition_point.y)
&& loc.x > bounds.0 .0
&& loc.x < bounds.0 .1
&& loc.x >= bounds.0 .0
&& loc.x <= bounds.0 .1
&& loc.y > bounds.1 .0
&& loc.y < bounds.1 .1
{
@ -1050,6 +1058,10 @@ impl PipSelector {
candidates += 1;
// a stack, to do recursion, because we need that i guess
let mut pips = vec![];
const MAX_PIP_SEARCH_DEPTH: usize = 3;
if loc.y == partition_point.y {
// pip is on east-west border
@ -1059,21 +1071,42 @@ impl PipSelector {
(false, false, false);
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(pip)) {
pips.push((src_pip, 0));
}
while let Some((src_pip, depth)) = pips.pop() {
let src_pip_coord: Coord = ctx.pip_location(src_pip).into();
if (src_pip_coord.x < partition_point.x) == (loc.x < partition_point.x) {
src_has_middle |= src_pip_coord.y == loc.y;
if (src_pip_coord.x < partition_point.x) && (loc.x < partition_point.x)
|| (src_pip_coord.x > partition_point.x) && (loc.x > partition_point.x)
{
src_has_east |= src_pip_coord.is_east_of(&partition_point.into());
src_has_west |= src_pip_coord.is_west_of(&partition_point.into());
if src_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
pips.push((src_pip, depth + 1));
}
}
}
}
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(pip)) {
pips.push((dst_pip, 0));
}
while let Some((dst_pip, depth)) = pips.pop() {
let dst_pip_coord: Coord = ctx.pip_location(dst_pip).into();
if (dst_pip_coord.x < partition_point.x) == (loc.x < partition_point.x) {
dst_has_middle |= dst_pip_coord.y == loc.y;
if (dst_pip_coord.x < partition_point.x) && (loc.x < partition_point.x)
|| (dst_pip_coord.x > partition_point.x) && (loc.x > partition_point.x)
{
dst_has_east |= dst_pip_coord.is_east_of(&partition_point.into());
dst_has_west |= dst_pip_coord.is_west_of(&partition_point.into());
if dst_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
pips.push((dst_pip, depth + 1));
}
}
}
}
if (src_has_east && (dst_has_west || dst_has_middle))
|| (src_has_middle && dst_has_west)
{
@ -1103,21 +1136,44 @@ impl PipSelector {
(false, false, false);
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(pip)) {
pips.push((src_pip, 0));
}
while let Some((src_pip, depth)) = pips.pop() {
let src_pip_coord: Coord = ctx.pip_location(src_pip).into();
if (src_pip_coord.y < partition_point.y) == (loc.y < partition_point.y) {
src_has_middle |= src_pip_coord.x == loc.x;
if (src_pip_coord.y < partition_point.y) && (loc.y < partition_point.y)
|| (src_pip_coord.y > partition_point.y) && (loc.y > partition_point.y)
{
src_has_north |= src_pip_coord.is_north_of(&partition_point.into());
src_has_south |= src_pip_coord.is_south_of(&partition_point.into());
if src_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
// yaaaaaaay, we need to everything again for this pip :)
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
pips.push((src_pip, depth + 1));
}
}
}
}
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(pip)) {
pips.push((dst_pip, 0));
}
while let Some((dst_pip, depth)) = pips.pop() {
let dst_pip_coord: Coord = ctx.pip_location(dst_pip).into();
if (dst_pip_coord.y < partition_point.y) == (loc.y < partition_point.y) {
dst_has_middle |= dst_pip_coord.x == loc.x;
if (dst_pip_coord.y < partition_point.y) && (loc.y < partition_point.y)
|| (dst_pip_coord.y > partition_point.y) && (loc.y > partition_point.y)
{
dst_has_north |= dst_pip_coord.is_north_of(&partition_point.into());
dst_has_south |= dst_pip_coord.is_south_of(&partition_point.into());
if dst_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
pips.push((dst_pip, depth + 1));
}
}
}
}
if (src_has_north && (dst_has_south || dst_has_middle))
|| (src_has_middle && dst_has_south)
{
@ -1264,16 +1320,13 @@ impl PipSelector {
let pips = &self.pips[pip_index];
let selected_pip = self
let (selected_pip, mut candidate, mut source, mut sink) = self
.pip_index_to_position_iter(pip_index, (desired_pip_location.x, desired_pip_location.y))
.flat_map(|pos| {
pips.get(&pos)
.unwrap_or_else(|| panic!("tried at {:?}", pos))
.iter()
})
.find(|&pip| {
.flat_map(|pos| pips.get(&pos))
.flat_map(|vec| vec.iter())
.filter_map(|pip| {
if !ctx.pip_avail_for_net(*pip, raw_net) {
return false;
return None;
}
let source = ctx.pip_src_wire(*pip);
@ -1285,7 +1338,7 @@ impl PipSelector {
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
(source, sink)
}
Ordering::Equal => return false,
Ordering::Equal => return None,
Ordering::Less => {
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
let source = self.used_wires.get(&source).unwrap().lock().unwrap();
@ -1295,21 +1348,18 @@ impl PipSelector {
let mut candidate = self.used_pips.get(pip).unwrap().lock().unwrap();
if candidate.map(|other| other != net).unwrap_or(false) {
return false;
return None;
}
if source.map(|other| other != net).unwrap_or(false) {
return false;
return None;
}
if sink.map(|other| other != net).unwrap_or(false) {
return false;
return None;
}
*candidate = Some(net);
*source = Some(net);
*sink = Some(net);
true
})?;
Some((pip, candidate, source, sink))
})
.next()?;
{
let mut cache = self.pip_selection_cache[pip_index]
@ -1317,9 +1367,19 @@ impl PipSelector {
.unwrap()
.write()
.unwrap();
// while we were looking, someone else might have found a pip
if let Some(other_pip) = *cache {
return Some(other_pip);
}
*cache = Some(*selected_pip);
}
*candidate = Some(net);
*source = Some(net);
*sink = Some(net);
Some(*selected_pip)
}
@ -1354,7 +1414,7 @@ impl PipSelector {
0 | 2 => (
(1, 0),
self.partition_loc.x - start_position.0 - 1,
start_position.0 - self.boundaries.0 .0 - 1,
start_position.0 - self.boundaries.0 .0,
),
1 | 3 => (
(1, 0),
@ -1364,7 +1424,7 @@ impl PipSelector {
4 | 6 => (
(0, 1),
self.partition_loc.y - start_position.1 - 1,
start_position.1 - self.boundaries.1 .0 - 1,
start_position.1 - self.boundaries.1 .0,
),
5 | 7 => (
(0, 1),