Removed (now unused) dependency to Lemon/Coin-OR
This commit is contained in:
parent
1a439d1b5d
commit
77c4277482
|
@ -1,147 +0,0 @@
|
||||||
|
|
||||||
#include "coloquinte/detailed.hxx"
|
|
||||||
#include "coloquinte/circuit_helper.hxx"
|
|
||||||
|
|
||||||
#include <lemon/smart_graph.h>
|
|
||||||
#include <lemon/network_simplex.h>
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace coloquinte{
|
|
||||||
namespace dp{
|
|
||||||
|
|
||||||
void optimize_on_topology_HPWL(netlist const & circuit, detailed_placement & pl){
|
|
||||||
// Solves a minimum cost flow problem to optimize the placement at fixed topology
|
|
||||||
// Concretely, it means aligning the pins to minimize the wirelength
|
|
||||||
// It uses the Lemon network simplex solver from the Coin-OR initiative, which should scale well up to hundred of thousands of cells
|
|
||||||
|
|
||||||
using namespace lemon;
|
|
||||||
DIGRAPH_TYPEDEFS(SmartDigraph);
|
|
||||||
// Create a graph with the cells and bounds of the nets as node
|
|
||||||
SmartDigraph g;
|
|
||||||
|
|
||||||
std::vector<Node> cell_nodes(circuit.cell_cnt());
|
|
||||||
for(index_t i=0; i<circuit.cell_cnt(); ++i){
|
|
||||||
if((circuit.get_cell(i).attributes & XMovable) != 0)
|
|
||||||
cell_nodes[i] = g.addNode();
|
|
||||||
}
|
|
||||||
std::vector<Node> Lnet_nodes(circuit.net_cnt()), Unet_nodes(circuit.net_cnt());
|
|
||||||
for(index_t i=0; i<circuit.net_cnt(); ++i){
|
|
||||||
if(circuit.get_net(i).pin_cnt > 0){
|
|
||||||
Lnet_nodes[i] = g.addNode();
|
|
||||||
Unet_nodes[i] = g.addNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Two nodes for position constraints
|
|
||||||
Node fixed = g.addNode();
|
|
||||||
|
|
||||||
typedef std::pair<SmartDigraph::Arc, int_t> arc_pair;
|
|
||||||
typedef std::pair<SmartDigraph::Node, int_t> node_pair;
|
|
||||||
// The arcs corresponding to constraints of the original problem
|
|
||||||
std::vector<arc_pair> constraint_arcs;
|
|
||||||
|
|
||||||
// Now we add every positional constraint, which becomes an arc in the min-cost flow problem
|
|
||||||
for(index_t i=0; i<circuit.cell_cnt(); ++i){ // The cells
|
|
||||||
for(index_t l = pl.neighbours_limits_[i]; l < pl.neighbours_limits_[i+1]; ++l){
|
|
||||||
index_t oi = pl.neighbours_[l].second;
|
|
||||||
if(oi == null_ind) continue;
|
|
||||||
|
|
||||||
if((circuit.get_cell(i).attributes & XMovable) != 0 and (circuit.get_cell(oi).attributes & XMovable) != 0){
|
|
||||||
// Two movable cells: OK
|
|
||||||
auto A = g.addArc(cell_nodes[oi], cell_nodes[i]);
|
|
||||||
constraint_arcs.push_back(arc_pair(A, -circuit.get_cell(i).size.x));
|
|
||||||
}
|
|
||||||
else if((circuit.get_cell( i).attributes & XMovable) != 0){
|
|
||||||
// The cell c is movable and constrained on the right
|
|
||||||
auto A = g.addArc(fixed, cell_nodes[i]);
|
|
||||||
constraint_arcs.push_back(arc_pair(A, pl.plt_.positions_[oi].x - circuit.get_cell(i).size.x));
|
|
||||||
}
|
|
||||||
else if((circuit.get_cell(oi).attributes & XMovable) != 0){
|
|
||||||
// The cell oc is movable and constrained on the left
|
|
||||||
auto A = g.addArc(cell_nodes[oi], fixed);
|
|
||||||
constraint_arcs.push_back(arc_pair(A, -pl.plt_.positions_[i].x - circuit.get_cell(i).size.x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for(index_t r=0; r<pl.row_cnt(); ++r){ // And the boundaries of each row
|
|
||||||
index_t lc = pl.row_first_cells_[r];
|
|
||||||
if(lc != null_ind and (circuit.get_cell(lc).attributes & XMovable) != 0){
|
|
||||||
auto Al = g.addArc(cell_nodes[lc], fixed);
|
|
||||||
constraint_arcs.push_back(arc_pair(Al, -pl.min_x_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(index_t r=0; r<pl.row_cnt(); ++r){ // And the boundaries of each row
|
|
||||||
index_t rc = pl.row_last_cells_[r];
|
|
||||||
if(rc != null_ind and (circuit.get_cell(rc).attributes & XMovable) != 0){
|
|
||||||
auto Ar = g.addArc(fixed, cell_nodes[rc]);
|
|
||||||
constraint_arcs.push_back(arc_pair(Ar, pl.max_x_ - circuit.get_cell(rc).size.x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// And every pin of every net: arcs too
|
|
||||||
for(index_t n=0; n<circuit.net_cnt(); ++n){
|
|
||||||
for(auto p : circuit.get_net(n)){
|
|
||||||
index_t c = p.cell_ind;
|
|
||||||
int_t pin_offs = (pl.plt_.orientations_[c].x ? p.offset.x : circuit.get_cell(c).size.x - p.offset.x); // Offset to the beginning of the cell
|
|
||||||
if((circuit.get_cell(c).attributes & XMovable) != 0){
|
|
||||||
Arc Al = g.addArc(cell_nodes[c], Lnet_nodes[n]);
|
|
||||||
constraint_arcs.push_back(arc_pair(Al, pin_offs));
|
|
||||||
Arc Ar = g.addArc(Unet_nodes[n], cell_nodes[c]);
|
|
||||||
constraint_arcs.push_back(arc_pair(Ar, -pin_offs));
|
|
||||||
}
|
|
||||||
else{ // Fixed offset
|
|
||||||
auto Al = g.addArc(fixed, Lnet_nodes[n]);
|
|
||||||
constraint_arcs.push_back(arc_pair(Al, pl.plt_.positions_[c].x + pin_offs));
|
|
||||||
auto Ar = g.addArc(Unet_nodes[n], fixed);
|
|
||||||
constraint_arcs.push_back(arc_pair(Ar, - pl.plt_.positions_[c].x - pin_offs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then the only capacitated arcs: the ones for the nets
|
|
||||||
std::vector<node_pair> net_supplies;
|
|
||||||
for(index_t n=0; n<circuit.net_cnt(); ++n){
|
|
||||||
if(circuit.get_net(n).pin_cnt > 0){
|
|
||||||
net_supplies.push_back(node_pair(Unet_nodes[n], circuit.get_net(n).weight));
|
|
||||||
net_supplies.push_back(node_pair(Lnet_nodes[n], -circuit.get_net(n).weight));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the maps to have cost and capacity for the arcs
|
|
||||||
IntArcMap cost(g, 0);
|
|
||||||
IntArcMap capacity(g, circuit.net_cnt());
|
|
||||||
IntNodeMap supply(g, 0);
|
|
||||||
|
|
||||||
for(arc_pair A : constraint_arcs){
|
|
||||||
cost[A.first] = A.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(node_pair N : net_supplies){
|
|
||||||
supply[N.first] = N.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then we (hope the solver can) solve it
|
|
||||||
NetworkSimplex<SmartDigraph> ns(g);
|
|
||||||
ns.supplyMap(supply).costMap(cost);
|
|
||||||
auto res = ns.run();
|
|
||||||
if(res != ns.OPTIMAL){
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// And we get the new positions as the dual values of the current solution (compared to the fixed pin)
|
|
||||||
for(index_t c=0; c<circuit.cell_cnt(); ++c){ // The cells
|
|
||||||
if((circuit.get_cell(c).attributes & XMovable) != 0){
|
|
||||||
pl.plt_.positions_[c].x = ns.potential(cell_nodes[c]) - ns.potential(fixed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pl.selfcheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dp
|
|
||||||
} // namespace coloquinte
|
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,6 @@ void OSRP_convex_RSMT(netlist const & circuit, detailed_placement & pl);
|
||||||
void OSRP_noncvx_HPWL(netlist const & circuit, detailed_placement & pl);
|
void OSRP_noncvx_HPWL(netlist const & circuit, detailed_placement & pl);
|
||||||
void OSRP_noncvx_RSMT(netlist const & circuit, detailed_placement & pl);
|
void OSRP_noncvx_RSMT(netlist const & circuit, detailed_placement & pl);
|
||||||
|
|
||||||
void optimize_on_topology_HPWL(netlist const & circuit, detailed_placement & pl);
|
|
||||||
|
|
||||||
void row_compatible_orientation(netlist const & circuit, detailed_placement & pl, bool first_row_orient);
|
void row_compatible_orientation(netlist const & circuit, detailed_placement & pl, bool first_row_orient);
|
||||||
|
|
||||||
} // namespace dp
|
} // namespace dp
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
.. |FC13| replace:: :sc:`fc13`
|
.. |FC13| replace:: :sc:`fc13`
|
||||||
.. |Debian| replace:: :sc:`Debian`
|
.. |Debian| replace:: :sc:`Debian`
|
||||||
.. |Ubuntu| replace:: :sc:`Ubuntu`
|
.. |Ubuntu| replace:: :sc:`Ubuntu`
|
||||||
.. |LEMON| replace:: :sc:`lemon`
|
|
||||||
.. |Coin-Or| replace:: :sc:`coin-or`
|
|
||||||
|
|
||||||
.. |Alexandre| replace:: :sc:`Alexandre`
|
.. |Alexandre| replace:: :sc:`Alexandre`
|
||||||
.. |Belloeil| replace:: :sc:`Belloeil`
|
.. |Belloeil| replace:: :sc:`Belloeil`
|
||||||
|
@ -128,7 +126,6 @@
|
||||||
.. _Box Router: http://www.cerc.utexas.edu/~thyeros/boxrouter/boxrouter.htm
|
.. _Box Router: http://www.cerc.utexas.edu/~thyeros/boxrouter/boxrouter.htm
|
||||||
.. _hMETIS: http://glaros.dtc.umn.edu/gkhome/views/metis
|
.. _hMETIS: http://glaros.dtc.umn.edu/gkhome/views/metis
|
||||||
.. _Knik Thesis: http://www-soc.lip6.fr/en/users/damiendupuis/PhD/
|
.. _Knik Thesis: http://www-soc.lip6.fr/en/users/damiendupuis/PhD/
|
||||||
.. _Coin Or Home: http://www.coin-or.org/index.html
|
|
||||||
.. _RapidJSON: http://miloyip.github.io/rapidjson/
|
.. _RapidJSON: http://miloyip.github.io/rapidjson/
|
||||||
|
|
||||||
.. _coriolis2-1.0.2049-1.slsoc6.i686.rpm: http://asim.lip6.fr/pub/coriolis/2.0/coriolis2-1.0.2049-1.slsoc6.i686.rpm
|
.. _coriolis2-1.0.2049-1.slsoc6.i686.rpm: http://asim.lip6.fr/pub/coriolis/2.0/coriolis2-1.0.2049-1.slsoc6.i686.rpm
|
||||||
|
@ -377,15 +374,8 @@ Building documentation prerequisites:
|
||||||
|
|
||||||
Optional libraries:
|
Optional libraries:
|
||||||
|
|
||||||
* `Lemon <https://www.si2.org/>`_ (used by the detailed placer)
|
|
||||||
* LEF/DEF (from `SI2 <https://www.si2.org/>`_)
|
* LEF/DEF (from `SI2 <https://www.si2.org/>`_)
|
||||||
|
|
||||||
The |Coloquinte| component requires the |LEMON| component from |Coin-Or| (`Coin Or Home`_).
|
|
||||||
A repository of |Coin-Or| packages backported from |Fedora| 21 is available here:
|
|
||||||
|
|
||||||
* |SL6|: `ftp://pub/linux/distributions/slsoc/slsoc/soc/addons/i386/RPMS <http://ftp.lip6.fr/pub/linux/distributions/slsoc/slsoc/soc/addons/i386/repoview>`_
|
|
||||||
* |SL7|: `ftp://pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS <http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/repoview>`_
|
|
||||||
|
|
||||||
For other distributions, refer to their own packaging system.
|
For other distributions, refer to their own packaging system.
|
||||||
|
|
||||||
|newpage|
|
|newpage|
|
||||||
|
|
Loading…
Reference in New Issue