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