package org.cellocad.MIT.dnacompiler; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * Created by Bryan Der on 9/22/15. */ public class SequentialHelper { public static boolean convergeRPUs(LogicCircuit lc, GateLibrary gate_library, Args options, HashMap<String, ArrayList<ArrayList<Double>>> track_rpus) { Integer cycles = 0; while(! allGatesConverged(track_rpus)) { if(cycles > 1000) { return false; } updateRPUs(lc, gate_library, options, track_rpus); cycles++; } return true; } public static boolean allGatesConverged(HashMap<String, ArrayList<ArrayList<Double>>> track_rpus) { Double CONVERGENCE_THRESHOLD = 0.000000001; boolean all_converged = true; for(String gate_name: track_rpus.keySet()) { ArrayList<ArrayList<Double>> rpu_series = track_rpus.get(gate_name); if(rpu_series.size() < 5) { return false; } int i = rpu_series.size() - 1; ArrayList<Double> rpus_i = rpu_series.get(i); ArrayList<Double> rpus_iminus1 = rpu_series.get(i-1); //for each row in the truth table, check for convergence for(int j=0; j<rpus_i.size(); ++j) { Double diff = rpus_i.get(j) - rpus_iminus1.get(j); Double abs_diff = Math.abs(diff); if(abs_diff > CONVERGENCE_THRESHOLD) { //System.out.println("not converged " + gate_name); return false; } } } return all_converged; } public static void updateRPUs(LogicCircuit lc, GateLibrary gate_library, Args options, HashMap<String, ArrayList<ArrayList<Double>>> track_rpus) { ArrayList<Gate> gates = new ArrayList<Gate>(); gates.addAll( lc.get_logic_gates() ); gates.addAll( lc.get_output_gates() ); for(Gate g: gates) { g.set_unvisited(true); Evaluate.simulateRPU(g, gate_library, options); } //update the list of cycles for(Gate g: lc.get_Gates()) { ArrayList<Double> copy_rpus = new ArrayList<Double>(g.get_outrpus()); track_rpus.get(g.Name).add(copy_rpus); } } public static void setInitialRPUs(LogicCircuit lc, GateLibrary gate_library) { Evaluate.refreshGateAttributes(lc, gate_library); for(Gate g: lc.get_input_gates()) { ArrayList<Double> rpus = new ArrayList<Double>(); for(int i=0; i<g.get_logics().size(); ++i) { Integer logic = g.get_logics().get(i); if (logic == 0) { Double rpu = gate_library.get_INPUTS_OFF().get(g.Name); rpus.add(rpu); } else { Double rpu = gate_library.get_INPUTS_ON().get(g.Name); rpus.add(rpu); } } g.set_outrpus(rpus); } for(Gate g: lc.get_logic_gates()) { ArrayList<Double> rpus = new ArrayList<Double>(); for (int i = 0; i < g.get_logics().size(); ++i) { Integer logic = g.get_logics().get(i); if (logic == 0) { Double output_rpu = 0.0001; if(g.get_params().containsKey("ymin")) { output_rpu = g.get_params().get("ymin"); } rpus.add(output_rpu); } else { Double output_rpu = 100.0; if(g.get_params().containsKey("ymax")) { output_rpu = g.get_params().get("ymax"); } rpus.add(output_rpu); } } g.set_outrpus(rpus); } //TODO not sufficient for OUTPUT_OR for(Gate g: lc.get_output_gates()) { ArrayList<Double> rpus = new ArrayList<Double>(g.Outgoing.To.get_outrpus()); g.set_outrpus(rpus); } } public static void printTruthTable(LogicCircuit lc) { String tt = "\n"; for(Gate g: lc.get_Gates()) { tt += String.format("%7s", g.Name); } tt += "\n"; for(int i=0; i<lc.get_input_gates().get(0).get_logics().size(); ++i) { for(Gate g: lc.get_Gates()) { tt += String.format("%7s", g.get_logics().get(i)); } tt += "\n"; } System.out.println(tt); } public static void setInitialLogics(LogicCircuit lc, HashMap<String, List<Integer>> initial_logics, Integer nrows) { for (Gate g : lc.get_Gates()) { ArrayList<Integer> logics = new ArrayList<>(); for(int i=0; i<nrows; ++i) { logics.add(0); } g.set_logics(logics); } for(String gate_name: initial_logics.keySet()) { List<Integer> logics = initial_logics.get(gate_name); //g.Group: for S, R, Qa, Qb latch naming for(Gate g: lc.get_input_gates()) { if(g.Name.equals(gate_name)) { g.set_logics(new ArrayList<Integer>(logics)); } } for(Gate g: lc.get_logic_gates()) { if(g.Name.equals(gate_name)) { g.set_logics(new ArrayList<Integer>(logics)); } } for(Gate g: lc.get_output_gates()) { if(g.Name.equals(gate_name)) { g.set_logics(new ArrayList<Integer>(logics)); Gate child = g.Outgoing.To; child.set_logics(new ArrayList<Integer>(logics)); } } } } public static void updateLogics(LogicCircuit lc) { for(Gate g: lc.get_Gates()) { if(g.Type == Gate.GateType.INPUT) { continue; } else { ArrayList<Integer> output_logics = GateUtil.computeGateLogics(g); g.set_logics(output_logics); } } } public static boolean validLogic(LogicCircuit lc) { for(Gate g: lc.get_Gates()) { if(g.Type == Gate.GateType.INPUT) { continue; } for(int i=0; i<g.get_logics().size(); ++i) { Integer logic = g.get_logics().get(i); ArrayList<Integer> child_logics = new ArrayList<>(); for(Gate child: g.getChildren()) { child_logics.add(child.get_logics().get(i)); } Integer expected_logic = BooleanLogic.computeLogic(g.Type, child_logics); if(expected_logic != logic) { System.out.println(g.Group + " " + logic + " " + expected_logic + " : from " + child_logics.toString()); return false; } } } return true; } public static int loadInitialLogicsFromTruthtable(HashMap<String, List<Integer>> initial_logics, String fin_sequential_waveform) { ArrayList<String> file_lines = Util.fileLines(fin_sequential_waveform); for(String line: file_lines) { System.out.println(line); } String first_line = file_lines.get(0); HashMap<String, ArrayList<Integer>> io_logics_map = new HashMap(); ArrayList<String> labels = new ArrayList<String>(Util.lineTokenizer(first_line)); for(int i=0; i<labels.size(); ++i) { io_logics_map.put(labels.get(i), new ArrayList<Integer>()); } int nrows = 0; for(int j=1; j<file_lines.size(); ++j) { if(!file_lines.get(j).isEmpty()) { nrows++; ArrayList<String> tokens = new ArrayList<String>(Util.lineTokenizer(file_lines.get(j))); for (int i = 0; i < tokens.size(); ++i) { String label = labels.get(i); Integer val = Integer.valueOf(tokens.get(i)); io_logics_map.get(label).add(val); } } } for(String label: labels) { initial_logics.put(label, io_logics_map.get(label)); System.out.println("Initial logics " + label + " " + io_logics_map.get(label)); } return nrows; } public static void setInitialHistogramRPUs(LogicCircuit lc, GateLibrary gate_library) { Evaluate.refreshGateAttributes(lc, gate_library); for(Gate g: lc.get_input_gates()) { ArrayList<double[]> hist_rpus = new ArrayList<double[]>(); for(int i=0; i<g.get_logics().size(); ++i) { Integer logic = g.get_logics().get(i); if (logic == 0) { double[] hist_rpu = gate_library.get_INPUTS_HIST_OFF().get(g.Name); hist_rpus.add(hist_rpu); } else { double[] hist_rpu = gate_library.get_INPUTS_HIST_ON().get(g.Name); hist_rpus.add(hist_rpu); } } g.set_histogram_rpus(hist_rpus); } for(Gate g: lc.get_logic_gates()) { ArrayList<double[]> hist_rpus = new ArrayList<double[]>(); for (int i = 0; i < g.get_logics().size(); ++i) { Integer logic = g.get_logics().get(i); if (logic == 0) { Integer last_index = g.get_xfer_hist().get_xfer_interp().size() - 1; double[] hist_rpu = g.get_xfer_hist().get_xfer_interp().get(last_index); hist_rpus.add(hist_rpu); } else { double[] hist_rpu = g.get_xfer_hist().get_xfer_interp().get(0); hist_rpus.add(hist_rpu); } } g.set_histogram_rpus(hist_rpus); } //TODO not sufficient for OUTPUT_OR for(Gate g: lc.get_output_gates()) { ArrayList<double[]> hist_rpus = new ArrayList<double[]>(g.Outgoing.To.get_histogram_rpus()); g.set_histogram_rpus(hist_rpus); } } public static void convergeHistogramRPUs(LogicCircuit lc, GateLibrary gate_library, Args options, HashMap<String, ArrayList<ArrayList<double[]>>> track_rpus) { Integer cycles = 0; while(! allGateHistogramsConverged(track_rpus)) { updateHistogramRPUs(lc, gate_library, options, track_rpus); cycles++; } } public static boolean allGateHistogramsConverged(HashMap<String, ArrayList<ArrayList<double[]>>> track_rpus) { HistogramBins hbins = new HistogramBins(); hbins.init(); Double CONVERGENCE_THRESHOLD = 0.000000001; boolean all_converged = true; for(String gate_name: track_rpus.keySet()) { ArrayList<ArrayList<double[]>> rpu_series = track_rpus.get(gate_name); if(rpu_series.size() < 5) { return false; } int i = rpu_series.size() - 1; ArrayList<double[]> rpus_i = rpu_series.get(i); ArrayList<double[]> rpus_iminus1 = rpu_series.get(i-1); //for each row in the truth table, check for convergence for(int j=0; j<rpus_i.size(); ++j) { Double diff = HistogramUtil.median(rpus_i.get(j), hbins) - HistogramUtil.median(rpus_iminus1.get(j), hbins); Double abs_diff = Math.abs(diff); if(abs_diff > CONVERGENCE_THRESHOLD) { return false; } } } return all_converged; } public static void updateHistogramRPUs(LogicCircuit lc, GateLibrary gate_library, Args options, HashMap<String, ArrayList<ArrayList<double[]>>> track_rpus) { ArrayList<Gate> gates = new ArrayList<>(); gates.addAll( lc.get_logic_gates() ); gates.addAll( lc.get_output_gates() ); Evaluate.simulateHistogramRPU(lc, gate_library, options); //update the list of cycles for(Gate g: lc.get_Gates()) { ArrayList<double[]> copy_rpus = new ArrayList<double[]>(g.get_histogram_rpus()); track_rpus.get(g.Name).add(copy_rpus); } } }