001    
002    import java.util.concurrent.Executors;
003    import java.util.concurrent.ExecutorService;
004    import java.util.concurrent.Future;
005    import java.util.concurrent.ExecutionException;
006    
007    /**
008     * Parallel Matrix Multiplication using util.concurrent. 
009     * Using specified number of threads, 
010     * generating product matrix in blocks, matrix B is transposed.
011     */
012    
013    public class ConMultProcBlockTrans implements MMInf {
014    
015        int anzahl = 1;
016        int blocksize = 1;
017    
018        public ConMultProcBlockTrans(int threads, int size) {
019             anzahl = threads;
020             blocksize = size;
021        }
022    
023    
024    /**
025     * Performs the multiplication of two matrices, B transposed.
026     * C = A * transpose(B).
027     * @param C result matrix.
028     * @param A matrix.
029     * @param B matrix.
030     */
031        public void multiply(double[][] C, double[][] A, double[][] B) {
032          ExecutorService pool = Executors.newFixedThreadPool(anzahl);
033          Future[] f = new Future[A.length];
034          System.out.print("Starting " + anzahl + " threads");
035          System.out.print(", bs = " + (A.length/anzahl) + " ...");
036          System.out.print(", na = " + blocksize + " ...");
037          for (int i=0; i < anzahl; i++) {
038              f[i] = pool.submit( new ConRowMultProcBlockTrans(C,A,B,i,anzahl,blocksize) );
039          }
040          System.out.print(" started ...");
041          for (int i=0; i < anzahl; i++) {
042              try { 
043                  f[i].get(); 
044              } catch (InterruptedException ignored) { 
045              } catch (ExecutionException ignored) { 
046              }
047          }
048          pool.shutdown();
049          System.out.println(" done ConMultProcBlockTrans");
050        }
051    
052    }
053    
054    
055    /**
056     * This class is derived from the class Thread.
057     * It performs a row multiplication.
058     */
059    class ConRowMultProcBlockTrans extends Thread {
060    
061        double[][] A;
062        double[][] B;
063        double[][] C;
064        int i;  
065        int anzahl;
066        int blocksize;
067    
068    /**
069     * Constructor.
070     * @param Cp two dimensional result matrix.
071     * @param Ap two dimensional matrix.
072     * @param Bp two dimensional matrix.
073     */
074      ConRowMultProcBlockTrans(double[][] Cp, double[][] Ap, double[][] Bp, 
075                       int ip, int a, int s) {
076        A = Ap; B = Bp; C = Cp; 
077        i = ip; 
078        anzahl = a;
079        blocksize = s;
080      }
081    
082    /**
083     * Runs the multiplication.
084     */
085      public void run() {
086        int schritte = A.length / anzahl; 
087        if ( (A.length % anzahl) != 0 ) {
088            schritte++; // ceiling
089        }
090        int na = blocksize;
091        int nb = blocksize;
092    
093        for (int ii=i*schritte; ii < Math.min((i+1)*schritte,A.length); ii+=na) {
094            for (int jj=0; jj < B.length; jj+=nb) {
095    
096                for (int iii = ii; iii < Math.min((ii+na),A.length); iii++ ) {
097                    double[] Ai = A[iii];
098                    for (int j=jj; j < Math.min((jj+nb),B.length); j++) {
099                        double[] Bj = B[j];
100                        double c = 0.0;
101                        for (int k=0; k < Bj.length; k++) {
102                            c += Ai[k] * Bj[k];
103                        }
104                        C[iii][j] = c;
105                    }
106                }
107    
108            }
109        }
110    
111      }
112    
113    }