All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.javabdd.FindBestOrder Maven / Gradle / Ivy

//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2004-2023 John Whaley and others
//
// See the CONTRIBUTORS file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available under the
// terms of the GNU Library General Public License v2 or later, which is
// available at https://spdx.org/licenses/LGPL-2.0-or-later.html
//
// SPDX-License-Identifier: LGPL-2.0-or-later
//////////////////////////////////////////////////////////////////////////////

package com.github.javabdd;

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;
import java.util.StringTokenizer;

/**
 * Find best order.
 */
public class FindBestOrder {
    static BDDFactory bdd = null;

    boolean newbdd = true;

    BDD b1 = null;

    BDD b2 = null;

    BDDVarSet b3 = null;

    String filename0 = "fbo.bi";

    String filename1 = "fbo.1";

    String filename2 = "fbo.2";

    String filename3 = "fbo.3";

    /** How long to delay for loading, in ms. */
    long DELAY_TIME = Long.parseLong(System.getProperty("fbo.delaytime", "30000"));

    /** Factor how long to wait beyond the best time. */
    float FACTOR = Float.parseFloat(System.getProperty("fbo.waitfactor", "1.1"));

    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, BDDVarSet 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.toBDD());
        // 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();
            }
        }
    }

    @SuppressWarnings("deprecation")
    public long tryOrder(boolean reverse, String varOrder) {
        System.gc();
        TryThread t = new TryThread();
        t.reverse = reverse;
        t.varOrderToTry = varOrder;
        t.start();
        try {
            long waitTime = (long)(bestTotalTime * FACTOR) + 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;

        @Override
        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).toVarSet();
                    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 e) {
                    }
                }
            }
        }

        BDDDomain makeDomain(BDDFactory bdd, String name, int bits) {
            BDDDomain d = bdd.extDomain(new long[] {1L << bits})[0];
            d.setName(name);
            return d;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy