/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: DeltaBBMetric.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 Sun Microsystems and Static Free Software * * 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.database.geometry.Orientation; 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.tool.placement.genetic2.Reference; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * Class for evaluating delta-individuals in genetic algorithm and final placement solution. * This class uses bounding boxes of networks to estimate the wire length. */ public class DeltaBBMetric { static List<PlacementNode> nodesToPlace; static List<PlacementNetwork> allNetworks; static Reference ref; static List<Integer>[] networksOfNode; public static Map<PlacementNode, Integer> nodeBlocks; public static void init(List<PlacementNode> nodesToPlace, List<PlacementNetwork> allNetworks) { DeltaBBMetric.allNetworks = allNetworks; DeltaBBMetric.nodesToPlace = nodesToPlace; 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)); } networksOfNode = new LinkedList[nodesToPlace.size()]; for(int i = 0; i < networksOfNode.length; i++) { networksOfNode[i] = new LinkedList<Integer>(); } PlacementNode n; for(int i = 0; i < allNetworks.size(); i++) { PlacementNetwork w = allNetworks.get(i); List<PlacementPort> pp = w.getPortsOnNet(); for(PlacementPort p : pp) { n = p.getPlacementNode(); Integer ii = new Integer(i); if(!networksOfNode[nodeBlocks.get(n).intValue()].contains(ii)) networksOfNode[nodeBlocks.get(n).intValue()].add(ii); } } } public static void setRef(Reference ref) { DeltaBBMetric.ref = ref; } /** * 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 static double compute(List<Block> blocks, double[] netLengths) { double completeLength = ref.netLength; HashSet<Integer> changedNet = new HashSet<Integer>(); for(Block b : blocks) { for(Integer j : networksOfNode[b.getNr()]) { changedNet.add(j); } } for(Integer i : changedNet) { PlacementNetwork w = allNetworks.get(i.intValue()); List<PlacementPort> pp = w.getPortsOnNet(); 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();//nodeBlocks.get(p.getPlacementNode()); // these functions give us non-rotated offsets double offX = p.getOffX(); double offY = p.getOffY(); Block b = null; for(Block currBlock : blocks) if(currBlock.getNr() == blockId) b = currBlock; Orientation o; if(b != null) o = b.getOrientation(); else o = p.getPlacementNode().getPlacementOrientation(); 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; if(b != null) xpos = b.getX() + offX; else xpos = p.getPlacementNode().getPlacementX() + offX; double ypos; if(b != null) ypos = b.getY() + offY; else ypos = p.getPlacementNode().getPlacementY() + 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; } } netLengths[i.intValue()] = (right-left)+(top-bottom); //completeLength += (right-left)+(top-bottom); completeLength += netLengths[i.intValue()]; completeLength -= ref.netLengths[i.intValue()]; } return completeLength; } // non-accelerated version (deprecated) public static double old_compute(List<Block> blocks, double[] netLengths) { double completeLength = 0.0; int n = 0; // iterate over all networks and calculate the semiperimeter lengths for(PlacementNetwork w : allNetworks) { List<PlacementPort> pp = w.getPortsOnNet(); 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();//nodeBlocks.get(p.getPlacementNode()); // these functions give us non-rotated offsets double offX = p.getOffX(); double offY = p.getOffY(); Block b = null; for(Block currBlock : blocks) if(currBlock.getNr() == blockId) b = currBlock; Orientation o; if(b != null) o = b.getOrientation(); else o = p.getPlacementNode().getPlacementOrientation(); 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; if(b != null) xpos = b.getX() + offX; else xpos = p.getPlacementNode().getPlacementX() + offX; double ypos; if(b != null) ypos = b.getY() + offY; else ypos = p.getPlacementNode().getPlacementY() + 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); netLengths[n] = (right-left)+(top-bottom); n++; } return completeLength; } /** * Method to evaluate a placement given by the nodesToPlace. * @return the estimated wire length of the placement. */ public static double compute() { double completeLength = 0.0; // iterate over all networks and calculate the semiperimeter lengths List<PlacementPort> pp; double l,r,u,d; int n = 0; 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); ref.netLengths[n] = (r-l)+(u-d); n++; } return completeLength; } }