/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: StratCount.java * * Copyright (c) 2003 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.ncc.strategy; import java.util.TreeMap; import com.sun.electric.tool.ncc.NccGlobals; import com.sun.electric.tool.ncc.lists.LeafList; import com.sun.electric.tool.ncc.netlist.NetObject; import com.sun.electric.tool.ncc.netlist.Part; import com.sun.electric.tool.ncc.netlist.Port; import com.sun.electric.tool.ncc.netlist.Wire; import com.sun.electric.tool.ncc.trees.EquivRecord; /** StratCount counts and prints a tree's content. StratCount * implements a doFor method for each level in the EquivRecord tree, * keeping counters of what it finds. StratCount is for debugging and * program development. */ public class StratCount extends Strategy { // ------------------------------ types ----------------------------------- /** Object to maintain a statistical datum (an int) for each type of * NetObject. */ private static class NetObjStats { private static final int NUM_TYPES = 3; private int[] data = new int[NUM_TYPES]; NetObjStats(int initialVal) { for (int i=0; i<NUM_TYPES; i++) data[i] = initialVal; } public void incr(NetObject.Type type, int delta) { data[type.ordinal()] += delta; } public int get(NetObject.Type type) {return data[type.ordinal()];} public int getSumForAllTypes() { int sum = 0; for (int i=0; i<NUM_TYPES; i++) sum+=data[i]; return sum; } public String toString() { String out = ""; for (int i=0; i<NUM_TYPES; i++) { String v = String.valueOf(data[i]); out += rightJustifyInField(v, FIELD_WIDTH); } return out; } } private class SizeHistogram { TreeMap<Integer,NetObjStats> sizeToStats = new TreeMap<Integer,NetObjStats>(); void incr(NetObject.Type type, int size) { Integer sz = new Integer(size); NetObjStats stats = sizeToStats.get(sz); if (stats==null) { stats = new NetObjStats(0); sizeToStats.put(sz, stats); } stats.incr(type, 1); } void print() { globals.status2( spaces(INDENT_WIDTH)+ leftJustifyInField("LeafRec size", LABEL_WIDTH)+ rightJustifyInField("#Part_Recs", FIELD_WIDTH)+ rightJustifyInField("#Wire_Recs", FIELD_WIDTH)+ rightJustifyInField("#Port_Recs", FIELD_WIDTH)); for (Integer key : sizeToStats.keySet()) { NetObjStats stats = sizeToStats.get(key); printLine(rightJustifyInField(key.toString(), 7), stats); } } } public static class Counts { public final int numMatchedPartEquivRecs; public final int numMatchedWireEquivRecs; public final int numMismatchedPartEquivRecs; public final int numMismatchedWireEquivRecs; public final int numActivePartEquivRecs; public final int numActiveWireEquivRecs; public Counts(int matchPartER, int matchWireER, int mismatchPartER, int mismatchWireER, int activePartER, int activeWireER) { numMatchedPartEquivRecs = matchPartER; numMatchedWireEquivRecs = matchWireER; numMismatchedPartEquivRecs = mismatchPartER; numMismatchedWireEquivRecs = mismatchWireER; numActivePartEquivRecs = activePartER; numActiveWireEquivRecs = activeWireER; } public int numNotMatchedPartEquivRecs() { return numMismatchedPartEquivRecs + numActivePartEquivRecs; } public int numNotMatchedWireEquivRecs() { return numMismatchedWireEquivRecs + numActiveWireEquivRecs; } } // -------------------------- private data -------------------------------- private static final int INDENT_WIDTH = 4; private static final int LABEL_WIDTH = 30; private static final int FIELD_WIDTH = 15; private int maxDepth; //depth in the tree private int numInternalRecs; private NetObjStats numMismatchedNetObjs = new NetObjStats(0); private NetObjStats numMatchedNetObjs = new NetObjStats(0); private NetObjStats numActiveNetObjs = new NetObjStats(0); private NetObjStats numMismatchedLeafRecs = new NetObjStats(0); private NetObjStats numMatchedLeafRecs = new NetObjStats(0); private NetObjStats numActiveLeafRecs = new NetObjStats(0); private int numCircuits; private int totalEqGrpSize; private int numberOfWireConnections; private long numberOfWireConnectionsSquared; private int numberOfPartConnections; private String workingOnString; private NetObject.Type netObjType; private SizeHistogram sizeHistogram = new SizeHistogram(); private StratCount(NccGlobals globals) {super(globals);} private static String spaces(int num) { StringBuffer b = new StringBuffer(); for (int i=0; i<num; i++) b.append(" "); return b.toString(); } private static String rightJustifyInField(String s, int fieldWidth) { return spaces(fieldWidth - s.length()) + s; } private static String leftJustifyInField(String s, int fieldWidth) { return s + spaces(fieldWidth - s.length()); } private void printLine(String label, NetObjStats stats) { globals.status2(spaces(INDENT_WIDTH) + leftJustifyInField(label, LABEL_WIDTH) + stats.toString()); } private void printLine(String label, int data) { globals.status2(spaces(INDENT_WIDTH) + leftJustifyInField(label, LABEL_WIDTH) + rightJustifyInField(String.valueOf(data), FIELD_WIDTH)); } private void printLine(String label, double data) { data = Math.rint(data * 10)/10; globals.status2(spaces(INDENT_WIDTH) + leftJustifyInField(label, LABEL_WIDTH) + rightJustifyInField(String.valueOf(data), FIELD_WIDTH)); } // ---------- the tree walking code --------- //Get setup to start, initializing the counters. private void preamble(EquivRecord j){ startTime("StratCount", "statistics for entire equivalence class tree"); } // Print the results when finished. private Counts summary(){ // print a label globals.status2( spaces(INDENT_WIDTH + LABEL_WIDTH) + rightJustifyInField("Parts", FIELD_WIDTH) + rightJustifyInField("Wires", FIELD_WIDTH) + rightJustifyInField("Ports", FIELD_WIDTH)); printLine("# mismatched equiv classes", numMismatchedLeafRecs); printLine("# matched equiv classes", numMatchedLeafRecs); printLine("# active equiv classes", numActiveLeafRecs); printLine("# mismatched net objects", numMismatchedNetObjs); printLine("# matched net objects", numMatchedNetObjs); printLine("# active net objects", numActiveNetObjs); int numEquivRecs = numMismatchedLeafRecs.getSumForAllTypes() + numMatchedLeafRecs.getSumForAllTypes() + numActiveLeafRecs.getSumForAllTypes(); globals.status2(""); sizeHistogram.print(); globals.status2(""); //printLine("# InternalRecords", numInternalRecs); //printLine("# Circuits", numCircuits); printLine("max tree depth", maxDepth); //if (maxDepth>1000) System.out.println("Tell Russell that max tree depth = "+maxDepth); // float average= (float)totalEqGrpSize/(float)numEquivRecs; // printLine("average size EquivRec", average); // printLine("# pins", numberOfWireConnections); // // // # Wire pins must = # Part pins unless we're checking just the Wire // // sub-tree or just the Part sub-tree. // int diffPins = numberOfPartConnections - numberOfWireConnections; // int numWires = numMismatchedNetObjs.get(NetObject.Type.WIRE) + // numRetiredNetObjs.get(NetObject.Type.WIRE) + // numActiveNetObjs.get(NetObject.Type.WIRE); // int numParts = numMismatchedNetObjs.get(NetObject.Type.PART) + // numRetiredNetObjs.get(NetObject.Type.PART) + // numActiveNetObjs.get(NetObject.Type.PART); // error(numWires!=0 && numParts!=0 && diffPins!=0, // "#wirePins != #partPins: "+ // numberOfWireConnections+" != "+numberOfPartConnections); // // average= (float)numberOfWireConnections/(float)numWires; // double rms= (float)numberOfWireConnectionsSquared/(float)numWires; // rms= Math.sqrt(rms); // printLine("average wire pins", average); // printLine("rms wire pins", rms); elapsedTime(); return new Counts(numMatchedLeafRecs.get(NetObject.Type.PART), numMatchedLeafRecs.get(NetObject.Type.WIRE), numMismatchedLeafRecs.get(NetObject.Type.PART), numMismatchedLeafRecs.get(NetObject.Type.WIRE), numActiveLeafRecs.get(NetObject.Type.PART), numActiveLeafRecs.get(NetObject.Type.WIRE)); } public LeafList doFor(EquivRecord j){ if (j.isLeaf()) { doEquivRec((EquivRecord)j); } else { numInternalRecs++; } return super.doFor(j); } private void doEquivRec(EquivRecord er){ int erSize = er.maxSize(); totalEqGrpSize += erSize; netObjType = er.getNetObjType(); int numNetObjs = er.numNetObjs(); if (er.isMismatched()) { numMismatchedLeafRecs.incr(netObjType, 1); numMismatchedNetObjs.incr(netObjType, numNetObjs); sizeHistogram.incr(netObjType, erSize); } else if (er.isMatched()) { numMatchedLeafRecs.incr(netObjType, 1); numMatchedNetObjs.incr(netObjType, numNetObjs); sizeHistogram.incr(netObjType, erSize); } else { numActiveLeafRecs.incr(netObjType, 1); numActiveNetObjs.incr(netObjType, numNetObjs); sizeHistogram.incr(netObjType, erSize); } numCircuits += er.numCircuits(); } /** * doFor(NetObject) counts Wires and Parts. * It computes the total and the average number of connections on a Wire * and the root mean square (RMS) average number of connections. * It sums the total number of connections on Parts. * @return null. */ public Integer doFor(NetObject n){ error(n.getNetObjType()!=netObjType, "mixed type leaf record"); maxDepth = Math.max(maxDepth, getDepth()); if (n instanceof Wire) { doFor((Wire)n); } else if (n instanceof Part){ doFor((Part)n); } else { error(!(n instanceof Port), "expecting Port"); } return CODE_NO_CHANGE; } private void doFor(Wire w){ int n= w.numParts(); numberOfWireConnections += n; float nf= n; numberOfWireConnectionsSquared += nf*nf; } private void doFor(Part p){ numberOfPartConnections += p.numDistinctWires(); } // ----------------------- intended interface ----------------------------- public static Counts doYourJob(NccGlobals globals) { EquivRecord root = globals.getRoot(); StratCount jsc = new StratCount(globals); jsc.preamble(root); jsc.doFor(root); return jsc.summary(); } // public static LeafList doYourJob(RecordList g, // NccGlobals globals){ // StratCount jsc = new StratCount(globals); // jsc.preamble(g); // if (g.size()!=0) { // jsc.doFor(g); // jsc.summary(); // } // return new LeafList(); // } }