package decoder; import is2.data.Closed; import is2.data.DataF; import is2.data.Edges; import is2.data.Open; import java.util.ArrayList; import java.util.concurrent.Callable; /** * @author Bernd Bohnet, 30.08.2009 * * This class implements a parallel feature extractor. */ final public class ParallelDecoder implements Callable<Object> { // some constants private static final float INIT_BEST = (-1.0F / 0.0F); private static final boolean[] DIR = {false, true}; // the data space of the weights for a dependency tree final private DataF x; private short[] pos; private Open O[][][][]; private Closed C[][][][]; private int n; boolean done = false; public boolean waiting = false; /** * Initialize the parallel decoder. * * @param pos part-of-speech * @param d data * @param edges part-of-speech edge mapping * @param o open spans * @param c closed spans * @param n number of words */ public ParallelDecoder(short[] pos, DataF d, Open o[][][][], Closed c[][][][], int n) { this.pos = pos; this.x = d; this.O = o; this.C = c; this.n = n; } private static class DSet { short w1, w2; } @Override public Object call() { while (true) { DSet set = get(); if (done && set == null) { break; } if (set == null) { return null; } short s = set.w1, t = set.w2; for (short dir = 1; dir >= 0; dir--) { short[] labs = (dir == 1) ? Edges.get(pos[s], pos[t], false) : Edges.get(pos[t], pos[s], true); O[s][t][dir] = new Open[labs.length]; for (int l = O[s][t][dir].length - 1; l >= 0; l--) { double tRP = INIT_BEST; Closed tL = null, tR = null; for (int r = s; r < t; r++) { if (s == 0 && r != 0) { continue; } double tLPr = INIT_BEST, tRPr = INIT_BEST; Closed tLCld = null, tRCld = null; if (r == s) { tLPr = dir == 1 ? x.sib[s][t][s][0][l] : x.gra[t][s][s][1][l]; } else { for (int i = s + 1; i <= r; i++) { if (((dir == 1 ? x.sib[s][t][i][0][l] : x.gra[t][s][i][1][l]) + C[s][r][1][i].p) > tLPr) { tLPr = ((dir == 1 ? x.sib[s][t][i][0][l] : x.gra[t][s][i][1][l]) + C[s][r][1][i].p); tLCld = C[s][r][1][i]; } } } if (r == t - 1) { tRPr = dir == 1 ? x.gra[s][t][s][0][l] : x.sib[t][s][s][1][l]; } else { for (int i = r + 1; i < t; i++) { if (((dir == 1 ? x.gra[s][t][i][0][l] : x.sib[t][s][i][1][l]) + C[r + 1][t][0][i].p) > tRPr) { tRPr = ((dir == 1 ? x.gra[s][t][i][0][l] : x.sib[t][s][i][1][l]) + C[r + 1][t][0][i].p); tRCld = C[r + 1][t][0][i]; } } } if (tLPr + tRPr > tRP) { tRP = tLPr + tRPr; tL = tLCld; tR = tRCld; } } O[s][t][dir][l] = new Open(s, t, dir, labs[l], tL, tR, (float) (tRP + ((dir == 1) ? x.pl[s][t] : x.pl[t][s]) + ((dir == 1) ? x.lab[s][t][labs[l]][0] : x.lab[t][s][labs[l]][1]))); } } C[s][t][1] = new Closed[n]; C[s][t][0] = new Closed[n]; for (int m = s; m <= t; m++) { for (boolean d : DIR) { if ((d && m != s) || !d && (m != t && s != 0)) { // create closed structure double top = INIT_BEST; Open tU = null; Closed tL = null; int numLabels = O[(d ? s : m)][(d ? m : t)][d ? 1 : 0].length; //for (int l = numLabels-1; l >=0; l--) { for (int l = 0; l < numLabels; l++) { Open hi = O[(d ? s : m)][(d ? m : t)][d ? 1 : 0][l]; for (int amb = m + (d ? 1 : -1); amb != (d ? t : s) + (d ? 1 : -1); amb += (d ? 1 : -1)) { if ((hi.p + C[d ? m : s][d ? t : m][d ? 1 : 0][amb].p + x.gra[d ? s : t][m][amb][d ? 0 : 1][l]) > top) { top = (hi.p + C[d ? m : s][d ? t : m][d ? 1 : 0][amb].p + x.gra[d ? s : t][m][amb][(d ? 0 : 1)][l]); tU = hi; tL = C[d ? m : s][d ? t : m][d ? 1 : 0][amb]; } } if ((m == (d ? t : s)) && (hi.p + x.gra[d ? s : t][m][d ? s : t][(d ? 0 : 1)][l]) > top) { top = (hi.p + x.gra[(d ? s : t)][m][d ? s : t][d ? 0 : 1][l]); tU = hi; tL = null; } } C[s][t][d ? 1 : 0][m] = new Closed(s, t, m, d ? 1 : 0, tU, tL, (float) top); } } } } return null; } public static ArrayList<DSet> sets = new ArrayList<>(); static synchronized private DSet get() { synchronized (sets) { if (sets.isEmpty()) { return null; } return sets.remove(sets.size() - 1); } } public static void add(short w1, short w2) { DSet ds = new DSet(); ds.w1 = w1; ds.w2 = w2; sets.add(ds); } }