/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: BBMetric.java
* Written by Team 4: Benedikt Mueller, Richard Fallert
*
* This code has been developed at the Karlsruhe Institute of Technology (KIT), Germany,
* as part of the course "Multicore Programming in Practice: Tools, Models, and Languages".
* Contact instructor: Dr. Victor Pankratius (pankratius@ipd.uka.de)
*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Electric(tm) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.tool.placement.genetic2.metrics;
import com.sun.electric.tool.placement.PlacementFrame.PlacementNetwork;
import com.sun.electric.tool.placement.PlacementFrame.PlacementNode;
import com.sun.electric.tool.placement.PlacementFrame.PlacementPort;
import com.sun.electric.tool.placement.genetic2.Block;
import com.sun.electric.util.math.Orientation;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Class for evaluating individuals in genetic algorithm and final placement solution.
* This class uses bounding boxes of networks to estimate the wire length.
*/
public class BBMetric
{
private final boolean PARALLEL = false;
private List<PlacementNetwork> allNetworks;
private Map<PlacementNode, Integer> nodeBlocks;
public BBMetric(List<PlacementNode> nodesToPlace, List<PlacementNetwork> allNetworks)
{
this.allNetworks = allNetworks;
nodeBlocks = new HashMap<PlacementNode, Integer>();
Iterator<PlacementNode> it = nodesToPlace.iterator();
for(int i = 0; i < nodesToPlace.size(); i++)
{
nodeBlocks.put(it.next(), new Integer(i));
}
}
/**
* Method to evaluate a placement given by a blocks array.
* @param blocks the genome of an individual.
* @return the estimated wire length of the corresponding placement.
*/
public double compute(Block[] blocks)
{
double completeLength = 0.0;
if(PARALLEL)
{
BBThread bbThread1 = new BBThread(allNetworks, blocks, nodeBlocks, 0, allNetworks.size()>>1);
Thread t1 = new Thread(bbThread1);
t1.start();
BBThread bbThread2 = new BBThread(allNetworks, blocks, nodeBlocks, (allNetworks.size()>>1)+1, allNetworks.size());
Thread t2 = new Thread(bbThread2);
t2.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
completeLength += bbThread1.getBadness();
completeLength += bbThread2.getBadness();
}
else
{
// iterate over all networks and calculate the semiperimeter lengths
for(PlacementNetwork w : allNetworks)
{
List<PlacementPort> pp = w.getPortsOnNet();
if(w.getPortsOnNet().size() == 0)
{
System.out.println("HELP");
}
double left = Double.POSITIVE_INFINITY,
right = Double.NEGATIVE_INFINITY,
top = Double.NEGATIVE_INFINITY,
bottom = Double.POSITIVE_INFINITY;
// iterate over all PlacementPorts and calculate their bounding box
for(PlacementPort p : pp)
{
int blockId = nodeBlocks.get(p.getPlacementNode()).intValue();
// these functions give us non-rotated offsets
double offX = p.getOffX();
double offY = p.getOffY();
Orientation o = blocks[blockId].getOrientation();
if (o != Orientation.IDENT)
{
AffineTransform trans = o.pureRotate();
Point2D offset = new Point2D.Double(offX, offY);
trans.transform(offset, offset);
offX = offset.getX();
offY = offset.getY();
}
// the x,y coordinates of the PlacementPort according to the Individual
double xpos = blocks[blockId].getX() + offX;
double ypos = blocks[blockId].getY() + offY;
// calculates the bounding box
if(xpos < left)
{
left = xpos;
}
if(xpos > right)
{
right = xpos;
}
if(ypos > top)
{
top = ypos;
}
if(ypos < bottom)
{
bottom = ypos;
}
}
completeLength += (right-left)+(top-bottom);
}
}
return completeLength;
}
/**
* Method to evaluate a placement given by the nodesToPlace.
* @return the estimated wire length of the placement.
*/
public double compute()
{
double completeLength = 0.0;
// iterate over all networks and calculate the semiperimeter lengths
List<PlacementPort> pp;
double l,r,u,d;
for(PlacementNetwork w : allNetworks)
{
pp = w.getPortsOnNet();
if(w.getPortsOnNet().size() == 0)
{
System.exit(-1337);
}
l = (pp.get(0).getPlacementNode().getPlacementX() + pp.get(0).getRotatedOffX());
r = (pp.get(0).getPlacementNode().getPlacementX() + pp.get(0).getRotatedOffX());
u = (pp.get(0).getPlacementNode().getPlacementY() + pp.get(0).getRotatedOffY());
d = (pp.get(0).getPlacementNode().getPlacementY() + pp.get(0).getRotatedOffY());
// iterate over all PlacementPorts and calculate their bounding box
for(PlacementPort p : pp)
{
double xpos = p.getPlacementNode().getPlacementX() + p.getRotatedOffX();
double ypos = p.getPlacementNode().getPlacementY() + p.getRotatedOffY();
if(xpos < l)
{
l = xpos;
}
else
{
if(xpos > r)
{
r = xpos;
}
}
if(ypos < d)
{
d = ypos;
}
else
{
if(ypos > u)
{
u = ypos;
}
}
}
completeLength += (r-l)+(u-d);
}
return completeLength;
}
}