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