/** * histogram * * <p>Histogram overlap score worst-case = 0.0 and best-case = 1.0 */ public static void evaluateCircuitHistogramOverlap( LogicCircuit lc, GateLibrary gate_library, Args options) { // output gate _score (average) refreshGateAttributes(lc, gate_library); // if sequential if (options.get_circuit_type() == DNACompiler.CircuitType.sequential) { // set initial SequentialHelper.setInitialHistogramREUs(lc, gate_library); // track HashMap<String, ArrayList<ArrayList<double[]>>> track_reus = new HashMap<>(); for (Gate g : lc.get_Gates()) { track_reus.put(g.Name, new ArrayList<ArrayList<double[]>>()); ArrayList<double[]> copy_hist_reus = new ArrayList<double[]>(g.get_histogram_reus()); track_reus.get(g.Name).add(copy_hist_reus); track_reus.get(g.Name).add(copy_hist_reus); // looks for i-1 } // converge SequentialHelper.convergeHistogramREUs(lc, gate_library, options, track_reus); } // if combinational else if (options.get_circuit_type() == DNACompiler.CircuitType.combinational) { Evaluate.simulateHistogramREU(lc, gate_library, options); } double worst_out = Double.MAX_VALUE; for (int out = 0; out < lc.get_output_gates().size(); ++out) { Gate output = lc.get_output_gates().get(out); evaluateGateHistogramOverlap(output); if (output.get_scores().get_conv_overlap() < worst_out) { worst_out = output.get_scores().get_conv_overlap(); } } lc.get_scores().set_conv_overlap(worst_out); }
/** * ********************************************************************* * * <p>Synopsis [ ] * * <p>********************************************************************* */ public static void simulateHistogramREU(Gate g, GateLibrary gate_library, Args options) { if (g.is_unvisited()) { g.set_unvisited(false); ArrayList<Gate> children = g.getChildren(); for (Gate child : children) { if (child.is_unvisited()) { simulateHistogramREU(child, gate_library, options); } } // initialize g.get_histogram_reus().clear(); for (int i = 0; i < g.get_logics().size(); ++i) { // rows in truth table g.get_histogram_reus().add(new double[g.get_histogram_bins().get_NBINS()]); for (int j = 0; j < g.get_histogram_bins().get_NBINS(); ++j) { g.get_histogram_reus().get(i)[j] = 0.0; } } if (g.Type == GateType.OUTPUT_OR || g.Type == GateType.OUTPUT) { g.set_histogram_reus(GateUtil.getSumOfGateInputHistograms(g, gate_library, options)); } else if (g.Type == GateType.AND) { g.set_histogram_reus(GateUtil.getANDOfGateInputHistograms(g)); } else if (g.Type == GateType.NOT || g.Type == GateType.NOR) { // 2. For each row: for each bin: for each output bin: add normalizeToValue ArrayList<double[]> input_convreus = GateUtil.getSumOfGateInputHistograms(g, gate_library, options); g.set_in_histogram_reus(input_convreus); for (int i = 0; i < input_convreus.size(); ++i) { /*if(Args.dontcare_rows.contains(i)) { for(int bin=0; bin< g.get_histogram_reus().get(i).length; ++bin) { g.get_histogram_reus().get(i)[bin] = 0.0; } continue; }*/ double[] convhist = input_convreus.get(i); for (int bin = 0; bin < g.get_histogram_bins().get_NBINS(); ++bin) { double fractional_counts = convhist[bin]; double[] xslice = g.get_xfer_hist().get_xfer_interp().get(bin); for (int xslice_bin = 0; xslice_bin < g.get_histogram_bins().get_NBINS(); ++xslice_bin) { g.get_histogram_reus().get(i)[xslice_bin] += xslice[xslice_bin] * fractional_counts; } } } } // evaluateGateHistogramOverlap(g); //to compute gate scores } }
/** * score = 1 - penalty of histogram overlap score all ON:OFF pairs and report the worst score * * <p>overlap penalty: for each bin, compute geometric mean of two ON:OFF histogram values, add * add bin penalty to total penalty alternative is to penalize the min of the two ON:OFF histogram * values */ public static void evaluateGateHistogramOverlap(Gate g) { ArrayList<Double> scores_conv_overlap = new ArrayList<Double>(); ArrayList<Integer> ons = new ArrayList<Integer>(); ArrayList<Integer> offs = new ArrayList<Integer>(); // get ons and offs for (int i = 0; i < g.get_logics().size(); ++i) { if (g.get_logics().get(i) == 1) { ons.add(i); } else if (g.get_logics().get(i) == 0) { offs.add(i); } } // compute scores of all on-off pairs for (int on = 0; on < ons.size(); ++on) { for (int off = 0; off < offs.size(); ++off) { // if(!Args.dontcare_rows.contains(on) && !Args.dontcare_rows.contains(off)) { double median_on = Math.pow( Math.E, HistogramUtil.median( g.get_histogram_reus().get(ons.get(on)), g.get_histogram_bins())); double median_off = Math.pow( Math.E, HistogramUtil.median( g.get_histogram_reus().get(offs.get(off)), g.get_histogram_bins())); double score = 1 - median_off / median_on; double overlap_penalty = 0.0; // if ON histogram is lower than OFF histogram, broken circuit if (score < 0) { scores_conv_overlap.add(0.0); continue; } else { double[] on_norm = HistogramUtil.normalize(g.get_histogram_reus().get(ons.get(on))); double[] off_norm = HistogramUtil.normalize(g.get_histogram_reus().get(offs.get(off))); // penalty is sum of geometric means for each bin // total counts have been normalized to 1 for (int bin = 0; bin < g.get_histogram_bins().get_NBINS(); ++bin) { overlap_penalty += Math.sqrt(on_norm[bin] * off_norm[bin]); // geometric mean // overlap_penalty += Math.min( on_norm[bin] , off_norm[bin]); //min of the two bin // counts } } score = 1 - overlap_penalty; scores_conv_overlap.add(score); // } } } Collections.sort(scores_conv_overlap); g.get_scores().set_conv_overlap(scores_conv_overlap.get(0)); // worst }