package fr.lip6.kernel; import java.util.ArrayList; import java.util.Arrays; import fr.lip6.type.TrainingSample; /** * Simple multithreaded implementation over a given Kernel. The multithreading comes only when * computing the Gram matrix.
* Number of Threads is function of available processors. * @author dpicard * * @param */ public class ThreadedKernel extends Kernel { /** * */ private static final long serialVersionUID = -2193768216118832033L; protected Kernel k; private double[][] matrix; /** * MultiThread the given kernel * @param kernel */ public ThreadedKernel(Kernel kernel) { this.k = kernel; } @Override public double valueOf(T t1, T t2) { return k.valueOf(t1, t2); } @Override public double valueOf(T t1) { return k.valueOf(t1); } /* (non-Javadoc) * @see fr.lip6.kernel.Kernel#getKernelMatrix(java.util.ArrayList) */ @Override public double[][] getKernelMatrix(ArrayList> e) { matrix = new double[e.size()][e.size()]; int nbc = ((int)Math.sqrt(2*Runtime.getRuntime().availableProcessors()))+1; // int nbc = 1; int icrem = e.size()/nbc ; System.err.println("("+this.toString()+") Launching "+(nbc*nbc)+" block"); ArrayList threads = new ArrayList(); for(int i = 0 ; i < e.size() ; i+=icrem) for(int j = 0 ; j < e.size() ; j+=icrem) { MatrixThread t = new MatrixThread(matrix, e, i, i+icrem, j, j+icrem); threads.add(t); t.start(); } boolean cont = true; while(cont) { cont = false; for(MatrixThread t : threads) if(!t.hasFinished() && t.isAlive()) cont = true; Thread.yield(); } System.err.println("("+this.toString()+") done."); // for(int i = 0 ; i < e.size(); i++) // if(matrix[i][i] == 0) // { // System.out.println(toString()+" error calcul matrix : i="+i+" m="+matrix[i][i]); // System.out.println("kernel:"); // for(double[] d: matrix) // { // System.out.println(Arrays.toString(d)); // } // System.out.println(toString()+" error calcul matrix : i="+i+" m="+matrix[i][i]); // System.exit(0); // } return matrix; } private class MatrixThread extends Thread { double[][] m; ArrayList> e; int mini, maxi, minj, maxj; boolean finished = false; /** * @param m * @param e * @param mini * @param maxi * @param minj * @param maxj */ public MatrixThread(double[][] m, ArrayList> e, int mini, int maxi, int minj, int maxj) { this.m = m; this.e = e; this.mini = mini; this.maxi = Math.min(maxi, e.size()); this.minj = minj; this.maxj = Math.min(maxj, e.size()); } public void run() { finished = false; for (int i = mini; i < maxi; i++) { for (int j = minj; j < maxj; j++) { T t1 = e.get(i).sample; T t2 = e.get(j).sample; double v = valueOf(t1, t2); if(!Double.isNaN(v)) { m[i][j] = valueOf(t1, t2); } else { System.out.println("NAN : v="+v); System.out.println("t1="+Arrays.toString((double[])t1)); System.out.println("t1="+Arrays.toString((double[])t2)); System.exit(0); } } } finished = true; } public boolean hasFinished() { return finished; } } }