/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: SA_Test.java * Written by Team 2: Jan Barth, Iskandar Abudiab * * 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.simulatedAnnealing1; import com.sun.electric.tool.placement.PlacementFrame; import com.sun.electric.tool.placement.simulatedAnnealing1.metrics.AOMetric; import com.sun.electric.tool.placement.simulatedAnnealing1.metrics.BBMetric; import java.util.List; import java.util.Random; /** Parallel Placement **/ public class SA_Test extends PlacementFrame { private double INITIAL_TEMP = 10000000; // private int ITERATIONS = 100000; private int INNER_ITERATIONS = 200; private Random rand = new Random(); @Override public String getAlgorithmName() { return "SA_Test"; } /** * @see PlacementFrame#runPlacement(List, List, String); */ @Override protected void runPlacement(List<PlacementNode> nodesToPlace, List<PlacementNetwork> allNetworks, String cellName) { //variable declarations double temp = INITIAL_TEMP; double ratio = 0.99; //temp decline ratio double maxX = 0, maxY = 0; int accepts = 1; int declines = 1; // int acceptRate = 1; //integer is intentional // int stuckRate = 0; // int minSteps= 100; BBMetric bbMetric = new BBMetric( allNetworks ); PlacementNode[] nodes = new PlacementNode[nodesToPlace.size()]; for( int i = 0; i < nodesToPlace.size(); i++ ){ nodes[i] = nodesToPlace.get( i ); } AOMetric aoMetric = new AOMetric(nodes ); //random grid placement for (int i = 0; i < nodesToPlace.size(); i++ ) { PlacementNode n = nodes[i]; //TODO Change 200 to a variable number depending on the size of the nodes n.setPlacement(i * 1.0 % Math.sqrt(nodes.length) * 200, Math.round(i * 1.0 / Math.sqrt(nodes.length))* 200); } double w = 0; double h = 0; for(int i = 0; i < nodesToPlace.size(); i++){ PlacementNode n = nodes[i]; if( n.getWidth() > w ) w = n.getWidth(); if( n.getHeight() > h ) h = n.getHeight(); } // int numRows = (int)Math.round( Math.sqrt( nodesToPlace.size() ) ); // double xPos = 0, yPos = 0; // for(int i = 0; i < nodesToPlace.size(); i++){ // PlacementNode plNode = nodes[i]; // plNode.setPlacement( xPos, yPos ); // xPos += w; // if ( ( i%numRows ) == numRows-1 ) // { // xPos = 0; // yPos += h; // } // } //sandbox bounds for(PlacementNode node : nodes){ if( node.getPlacementX() > maxX ) maxX = node.getPlacementX(); if( node.getPlacementY() > maxY ) maxY = node.getPlacementY(); } //Step 1: GridPlacement double beforeScore = bbMetric.getScore(); System.out.println( "START: " + bbMetric.getScore() ); // while ( (accepts+declines < minSteps || acceptRate > 0)){ while ( temp > 0.01 ){ for( int i = 0; i < INNER_ITERATIONS; i++ ){ int index = (int) Math.round( rand.nextDouble()*( nodes.length - 1 ) ); int index2 = (int) Math.round( rand.nextDouble()*( nodes.length - 1 ) ); PlacementNode node1 = nodes[index]; PlacementNode node2 = nodes[index2]; double x1 = node1.getPlacementX(); double y1 = node1.getPlacementY(); double x2 = node2.getPlacementX(); double y2 = node2.getPlacementY(); // double newX = rand.nextDouble() * maxX; // double newY = rand.nextDouble() * maxY; node1.setPlacement( x2, y2 ); node2.setPlacement( x1, y1 ); double afterScore = bbMetric.getScore(); double delta = afterScore - beforeScore; if( !( delta < 0 ) && ! ( rand.nextDouble() < Math.exp( -delta / temp ) ) ) { node1.setPlacement( x1, y1 ); node2.setPlacement( x2, y2 ); declines += 1; // node1.setOrientation(node1.getPlacementOrientation().concatenate(Orientation.R)); // // double afterRotationScore = bbMetric.getScore(); // delta = afterRotationScore - beforeScore; // if( !( delta < 0 ) && ! ( rand.nextDouble() < Math.exp( -delta / temp ) ) ) { // node1.setOrientation(node1.getPlacementOrientation().concatenate(Orientation.X)); // } else{ // beforeScore = afterRotationScore; // } } else { accepts += 1; beforeScore = afterScore; } } temp *= ratio; // acceptRate = accepts / declines; System.out.println(temp); System.out.println( "SCORE: " + beforeScore ); System.out.println("Accepts=" + accepts + ", declines=" + declines + ", ratio=" + accepts / declines); } //Step 2: Run Moves and Rotations temp = INITIAL_TEMP; accepts = 1; declines = 1; beforeScore = aoMetric.getScore(); while (temp > 0.01) { for( int i = 0; i < INNER_ITERATIONS; i++ ){ int index = (int) Math.round( rand.nextDouble()*( nodes.length - 1 ) ); //int index2 = (int) Math.round( rand.nextDouble()*( nodes.length - 1 ) ); PlacementNode node1 = nodes[index]; //PlacementNode node2 = nodes[index2]; double x1 = node1.getPlacementX(); double y1 = node1.getPlacementY(); // double cx = maxX - x1; // double cy = maxY - y1; double newX = 0; double newY = 0; boolean sx = true; boolean sy = true; if ( x1 < maxX/2 ) { newX = x1 + rand.nextDouble() * ( node1.getWidth()/20 ); } else { newX = x1 - rand.nextDouble() * ( node1.getWidth()/20 ); sx = false; } if ( y1 < maxY/2 ){ newY = y1 + rand.nextDouble() * ( node1.getHeight()/20 ); } else { newY = y1 - rand.nextDouble() * ( node1.getHeight()/20 ); sy = false; } // double newX = rand.nextDouble() * maxX; // double newY = rand.nextDouble() * maxY; //Calculate new location // 1) select connection // int portIndex = (int) ((int) (node1.getPorts().size() - 1) * rand.nextDouble()); // PlacementPort p = node1.getPorts().get(portIndex); // // PlacementNetwork net = p.getPlacementNetwork(); // double x2; // double y2; // // if (net == null) { // continue; // } // // List<PlacementPort> ports = net.getPortsOnNet(); // // if (ports != null) { // int partnerPortIndex = (int)((ports.size()-1)* rand.nextDouble()); // PlacementPort partnerPort = net.getPortsOnNet().get(partnerPortIndex); // // x2 = partnerPort.getPlacementNode().getPlacementX() + partnerPort.getRotatedOffX(); // y2 = partnerPort.getPlacementNode().getPlacementY()+ partnerPort.getRotatedOffY(); // // double xDirection = (x1-x2) * (rand.nextDouble() / 0.6 + 0.2); // double yDirection = (y1-y2) * (rand.nextDouble() / 0.6 + 0.2); // double distance = Math.sqrt(xDirection * xDirection + yDirection * yDirection); // // x2 += distance / 8 - (distance / 4) * rand.nextDouble(); // y2 += distance / 8 - (distance / 4) * rand.nextDouble(); // // } else { // x2 = x1 - maxX + maxX * rand.nextDouble(); // y2 = y1 - maxY + maxY * rand.nextDouble(); // } // // node1.setPlacement( x2, y2 ); node1.setPlacement( newX, newY ); double afterScore = aoMetric.getScore(); double delta = afterScore - beforeScore; if( !( delta <= 0 ) ) { node1.setPlacement( x1, y1 ); declines += 1; if( rand.nextBoolean() ){ if ( sx ) { newX = x1 + rand.nextDouble() * ( node1.getWidth()/20 ); newY = y1; } else { newX = x1 - rand.nextDouble() * ( node1.getWidth()/20 ); newY = y1; } } else { if( sy ){ newX = x1; newY = y1 + rand.nextDouble() * ( node1.getHeight()/20 ); } else { newX = x1; newY = y1 - rand.nextDouble() * ( node1.getHeight()/20 ); } } node1.setPlacement( newX , newY ); // node1.setOrientation(node1.getPlacementOrientation().concatenate(Orientation.R)); // afterScore = aoMetric.getScore(); delta = afterScore - beforeScore; if( !( delta <= 0 ) ) { node1.setPlacement( x1 , y1 ); } else{ beforeScore = afterScore; accepts += 1; } } else { accepts += 1; beforeScore = afterScore; } } temp *= ratio; System.out.println(temp); System.out.println( "SCORE: " + beforeScore ); System.out.println("Accepts=" + accepts + ", declines=" + declines + ", ratio=" + accepts / declines); } //last step: transform placement back to the non-array for (int i = 0; i < nodes.length; i++) { nodesToPlace.set(i, nodes[i]); } System.out.println("Final Bounding Box: " + bbMetric.getScore()); } }