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 }