Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Placement #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/graph/logic/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ mod tests {

let mut fa = fa1.clone();
fa.graph.merge(fa2.graph);
println!("{}", fa.to_graphviz());

let mut transform = LogicGraphTransformer::new(fa);
transform.decompose_xor()?;
Expand Down
7 changes: 7 additions & 0 deletions src/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ impl GraphNodeKind {
_ => unreachable!(),
}
}

pub fn as_logic(&self) -> &Logic {
match self {
GraphNodeKind::Logic(logic) => logic,
_ => unreachable!(),
}
}
}

#[derive(Default, Debug, Clone)]
Expand Down
79 changes: 75 additions & 4 deletions src/transform/placer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use std::{collections::HashSet, iter::repeat_with};
use std::{
collections::{HashMap, HashSet},
default,
iter::repeat_with,
};

use petgraph::stable_graph::NodeIndex;
use eyre::ensure;
use itertools::Itertools;

use crate::{
graph::{
Expand All @@ -10,6 +15,7 @@ use crate::{
},
GraphNodeId, GraphNodeKind, SubGraphWithGraph,
},
logic::LogicType,
world::{block::Block, position::Position, world::World3D},
};

Expand Down Expand Up @@ -45,9 +51,10 @@ pub struct LocalPlacer<'a> {
}

pub const K_MAX_LOCAL_PLACE_NODE_COUNT: usize = 25;
pub const K_MAX_LOCAL_ROUTE_DISTANCE: usize = 5;

impl<'a> LocalPlacer<'a> {
// you should not pass side effected sub-graph
// you should not pass side effected partitioned sub-graph
pub fn new(
graph: SubGraphWithGraph<'a>,
try_count: usize,
Expand Down Expand Up @@ -89,9 +96,67 @@ impl<'a> LocalPlacer<'a> {
.0
}

fn next_place(&mut self) -> (WorldGraph, usize) {
fn populate_place_order(&self) -> Vec<Vec<GraphNodeId>> {
fn evaluate_place_order(order: Vec<GraphNodeId>) -> usize {
// TODO: calculate min-cut
todo!()
}

// TODO: order place order
vec![self.graph.topological_order()]
}

fn next_place(&self) -> (WorldGraph, usize) {
todo!()
}

// if place fail, then return false
fn try_place(
&self,
nodes: &mut HashMap<GraphNodeId, Vec<PlacedNode>>,
inputs: Vec<GraphNodeId>,
target: GraphNodeKind,
) -> eyre::Result<bool> {
ensure!(inputs.len() <= 2, "too many inputs");

let exists_pos: HashSet<Position> = nodes
.iter()
.map(|(_, nodes)| nodes.iter().map(|node| node.position).collect_vec())
.flatten()
.collect();

match target.as_logic().logic_type {
LogicType::Not => todo!(),
LogicType::Or => todo!(),
LogicType::And => eyre::bail!("currently, and placement not supports"),
LogicType::Xor => eyre::bail!("currently, xor placement not supports"),
}

Ok(true)
}

// route prev order output to next input
fn try_local_route(
&self,
nodes: &mut HashMap<GraphNodeId, Vec<PlacedNode>>,
outputs: Vec<GraphNodeId>,
input: GraphNodeId,
) -> eyre::Result<bool> {
if outputs.len() == 1 {
return Ok(true);
}

let v = outputs
.iter()
.map(|id| nodes[id].last().unwrap().position)
.collect_vec();

if v[0].distance(&v[1]) > K_MAX_LOCAL_ROUTE_DISTANCE {
return Ok(false);
}

Ok(true)
}
}

pub struct LocalPlacerCostEstimator<'a> {
Expand All @@ -109,3 +174,9 @@ impl<'a> LocalPlacerCostEstimator<'a> {
todo!()
}
}

#[derive(Default)]
pub enum LocalRouteStrategy {
#[default]
MinimumDistance,
}
46 changes: 28 additions & 18 deletions src/transform/world_to_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ impl WorldToLogicTransformer {
fn verify_input(graph: &WorldGraph) -> eyre::Result<()> {
// verify no repeater lock
let contains_lock_repeater = graph.graph.nodes.iter().any(|node| {
let GraphNodeKind::Block(block) = node.kind else {
return false;
let GraphNodeKind::Block(block) = node.kind else {
return false;
};

let BlockKind::Repeater { lock_input1, lock_input2 , ..} = block.kind else {
return false;
let BlockKind::Repeater {
lock_input1,
lock_input2,
..
} = block.kind
else {
return false;
};

lock_input1.is_some() || lock_input2.is_some()
Expand Down Expand Up @@ -154,27 +159,32 @@ mod tests {

#[test]
fn unittest_world_to_logic_graph() -> eyre::Result<()> {
let nbt = NBTRoot::load(&"test/alu.nbt".into())?;
let nbt = NBTRoot::load(&"test/xor.nbt".into())?;

let g = WorldGraphBuilder::new(&nbt.to_world()).build();
g.graph.verify()?;

let g = WorldToLogicTransformer::new(g)?.transform()?;
g.graph.verify()?;
// let g = WorldToLogicTransformer::new(g)?.transform()?;
// g.graph.verify()?;

// let mut transform = LogicGraphTransformer::new(g);
// transform.remove_double_neg_expression();
// transform.remove_double_neg_expression();
// transform.remove_double_neg_expression();
// let g = transform.finish();

let mut transform = LogicGraphTransformer::new(g);
transform.remove_double_neg_expression();
let sub_graphs = transform
.cluster(true)
.iter()
.map(|x| x.to_subgraph())
.collect_vec();
let g = transform.finish();
println!("{}", g.to_graphviz());
// let sub_graphs = transform
// .cluster(true)
// .iter()
// .map(|x| x.to_subgraph())
// .collect_vec();
// let g = transform.finish();

println!("{}", g.to_graphviz_with_clusters(&sub_graphs));
// println!("{}", g.to_graphviz_with_clusters(&sub_graphs));

let clustered_g = subgraphs_to_clustered_graph(&g.graph, &sub_graphs);
println!("{}", clustered_g.to_graphviz());
// let clustered_g = subgraphs_to_clustered_graph(&g.graph, &sub_graphs);
// println!("{}", clustered_g.to_graphviz());

Ok(())
}
Expand Down
4 changes: 4 additions & 0 deletions src/world/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ impl Position {
unreachable!()
}
}

pub fn distance(&self, tar: &Position) -> usize {
self.0.abs_diff(tar.0) + self.1.abs_diff(tar.1) + self.2.abs_diff(tar.2)
}
}

// 사이즈
Expand Down