// FindBestOrder.java, created Apr 2, 2004 10:43:21 PM 2004 by jwhaley
// Copyright (C) 2004 John Whaley <jwhaley@alum.mit.edu>
// Licensed under the terms of the GNU LGPL; see COPYING for details.
package net.sf.javabdd;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
/**
* FindBestOrder
*
* @author jwhaley
* @version $Id: FindBestOrder.java,v 1.1 2004/10/16 02:58:57 joewhaley Exp $
*/
public class FindBestOrder {
static BDDFactory bdd = null;
boolean newbdd = true;
BDD b1 = null;
BDD b2 = null;
BDD b3 = null;
String filename0 = "fbo.bi";
String filename1 = "fbo.1";
String filename2 = "fbo.2";
String filename3 = "fbo.3";
long DELAY_TIME = 30000;
BDDFactory.BDDOp op;
long bestCalcTime;
long bestTotalTime;
String bestOrder;
int nodeTableSize;
int cacheSize;
int maxIncrease;
File f0, f1, f2, f3;
public FindBestOrder(int nodeTableSize, int cacheSize, int maxIncrease,
long bestTime, long delayTime) {
this.bestCalcTime = bestTime;
this.bestTotalTime = Long.MAX_VALUE;
//this.nodeTableSize = b1.getFactory().getAllocNum();
this.nodeTableSize = nodeTableSize;
this.cacheSize = cacheSize;
this.maxIncrease = maxIncrease;
this.DELAY_TIME = delayTime;
}
public void init(BDD b1, BDD b2, BDD dom, BDDFactory.BDDOp op) throws IOException {
this.op = op;
f0 = File.createTempFile("fbo", "a");
filename0 = f0.getAbsolutePath();
f0.deleteOnExit();
f1 = File.createTempFile("fbo", "b");
filename1 = f1.getAbsolutePath();
f1.deleteOnExit();
f2 = File.createTempFile("fbo", "c");
filename2 = f2.getAbsolutePath();
f2.deleteOnExit();
f3 = File.createTempFile("fbo", "d");
filename3 = f3.getAbsolutePath();
f3.deleteOnExit();
//System.out.print("Writing BDDs to files...");
writeBDDConfig(b1.getFactory(), filename0);
b1.getFactory().save(filename1, b1);
b2.getFactory().save(filename2, b2);
dom.getFactory().save(filename3, dom);
//System.out.println("done.");
}
public void cleanup() {
//System.out.println("Cleaning up temporary files.");
f0.delete();
f1.delete();
f2.delete();
f3.delete();
if (b1 != null) b1.free();
if (b2 != null) b2.free();
if (b3 != null) b3.free();
}
public void writeBDDConfig(BDDFactory bdd, String fileName) throws IOException {
BufferedWriter dos = null;
try {
dos = new BufferedWriter(new FileWriter(fileName));
for (int i = 0; i < bdd.numberOfDomains(); ++i) {
BDDDomain d = bdd.getDomain(i);
dos.write(d.getName()+" "+d.size()+"\n");
}
} finally {
if (dos != null) dos.close();
}
}
public long tryOrder(boolean reverse, String varOrder) {
System.gc();
TryThread t = new TryThread();
t.reverse = reverse;
t.varOrderToTry = varOrder;
t.start();
try {
long waitTime = bestTotalTime + DELAY_TIME;
if (waitTime < 0L) waitTime = Long.MAX_VALUE;
t.join(waitTime);
} catch (InterruptedException x) {
}
t.stop();
Thread.yield(); // Help ThreadDeath exception to propagate.
if (t.totalTime == Long.MAX_VALUE) {
System.out.println("Thread taking too long, aborted.");
System.out.print("Free memory: "+Runtime.getRuntime().freeMemory());
b1 = null;
b2 = null;
b3 = null;
bdd = null;
newbdd = true;
System.gc();
System.out.println(" bytes -> "+Runtime.getRuntime().freeMemory()+" bytes");
}
if (t.time < bestCalcTime) {
bestOrder = varOrder;
bestCalcTime = t.time;
if (t.totalTime < bestTotalTime)
bestTotalTime = t.totalTime;
}
return t.time;
}
public String getBestOrder() {
return bestOrder;
}
public long getBestTime() {
return bestCalcTime;
}
public class TryThread extends Thread {
boolean reverse;
String varOrderToTry;
long time = Long.MAX_VALUE;
long totalTime = Long.MAX_VALUE;
public void run() {
long total = System.currentTimeMillis();
if (bdd == null) {
bdd = JFactory.init(nodeTableSize, cacheSize);
bdd.setMaxIncrease(maxIncrease);
readBDDConfig(bdd);
}
int[] varorder = bdd.makeVarOrdering(reverse, varOrderToTry);
bdd.setVarOrder(varorder);
//System.out.println("\nTrying ordering "+varOrderToTry);
try {
if (newbdd) {
b1 = bdd.load(filename1);
b2 = bdd.load(filename2);
b3 = bdd.load(filename3);
newbdd = false;
}
long t = System.currentTimeMillis();
BDD result = b1.applyEx(b2, op, b3);
time = System.currentTimeMillis() - t;
//b1.free(); b2.free(); b3.free();
result.free();
} catch (IOException x) {
}
System.out.println("Ordering: "+varOrderToTry+" time: "+time);
//bdd.done();
totalTime = System.currentTimeMillis() - total;
}
public void readBDDConfig(BDDFactory bdd) {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(filename0));
for (;;) {
String s = in.readLine();
if (s == null || s.equals("")) break;
StringTokenizer st = new StringTokenizer(s);
String name = st.nextToken();
long size = Long.parseLong(st.nextToken())-1;
makeDomain(bdd, name, BigInteger.valueOf(size).bitLength());
}
} catch (IOException x) {
} finally {
if (in != null) try { in.close(); } catch (IOException _) { }
}
}
BDDDomain makeDomain(BDDFactory bdd, String name, int bits) {
BDDDomain d = bdd.extDomain(new long[] { 1L << bits })[0];
d.setName(name);
return d;
}
}
}