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 }