001 /* 002 * $Id: MatrixMultMPI.java,v 1.5 2002/08/03 17:17:42 kredel Exp $ 003 */ 004 //package edu.unima.ky.parallel.mpijava; 005 006 import mpi.* ; 007 008 /** 009 * Matrix Multiplication. 010 * sequential and parallel using MPI. 011 * @author Akitoshi Yoshida 012 * @author Heinz Kredel. 013 */ 014 public class MatrixMultMPI { 015 016 /** 017 * @param C two-dimensional double array. 018 * @param A two-dimensional double array. 019 * @param B two-dimensional double array. 020 */ 021 public void seqmult(double[][] C, double[][] A, double[][] B) { 022 for (int i=0; i < A.length; i++) { 023 for (int j=0; j < B[0].length; j++) { 024 double c = 0.0; 025 for (int k=0; k < B.length; k++) { 026 c += A[i][k] * B[k][j]; 027 } 028 C[i][j] = c; 029 } 030 } 031 } 032 033 /** 034 * @param C two-dimensional double array. 035 * @param A two-dimensional double array. 036 * @param B two-dimensional double array. 037 * @throws MPIException. 038 */ 039 public void parmult(double[][] C, double[][] A, double[][] B) 040 throws MPIException { 041 042 boolean prnt = false; 043 044 // initialize MPI Communicators 045 int myid = MPI.COMM_WORLD.Rank() ; 046 int numprocs = MPI.COMM_WORLD.Size() ; 047 if (prnt) { 048 System.out.println("ExVecMPI on " + myid 049 + " of " + numprocs + " ") ; 050 } 051 int counts = A.length; 052 int[] assign = new int[counts]; 053 for (int k=0; k < counts; k++) { 054 assign[k] = k % numprocs; 055 } 056 057 /* transfer data */ 058 int msgtag = 4711; 059 if ( myid == 0 ) { 060 if (prnt) { 061 System.out.print("assign = "); 062 vecprint(assign); 063 System.out.print("sending A "); 064 } 065 for (int k=0; k < counts; k++ ) { 066 if ( myid != assign[k] ) { 067 MPI.COMM_WORLD.Send(A[k], 0, A[k].length, MPI.DOUBLE, assign[k], msgtag); 068 } 069 } 070 } else { 071 for (int y = 0; y < counts; y++ ) { 072 if ( myid == assign[y] ) { 073 MPI.COMM_WORLD.Recv(A[y], 0, A[y].length, MPI.DOUBLE, 0, msgtag); 074 } 075 } 076 } 077 if ( myid == 0 ) { 078 if (prnt) { 079 System.out.print("sending B "); 080 } 081 } 082 for (int x=0; x < B.length; x++ ){ 083 MPI.COMM_WORLD.Bcast(B[x], 0, B[x].length, MPI.DOUBLE, 0); 084 } 085 086 for (int i=0; i < counts; i++) { 087 if ( myid == assign[i] ) { 088 for (int j=0; j < B[0].length; j++) { 089 double c = 0.0; 090 for (int k=0; k < B.length; k++) { 091 c += A[i][k] * B[k][j]; 092 } 093 C[i][j] = c; 094 } 095 } 096 } 097 098 if ( myid == 0 ) { 099 if (prnt) { 100 System.out.print("receiving C "); 101 } 102 for (int k=0; k < counts; k++ ) { 103 if ( myid != assign[k] ) { 104 MPI.COMM_WORLD.Recv(C[k], 0, C[k].length, MPI.DOUBLE, assign[k], msgtag); 105 } 106 } 107 } else { 108 for (int y = 0; y < counts; y++ ) { 109 if ( myid == assign[y] ) { 110 MPI.COMM_WORLD.Send(C[y], 0, C[y].length, MPI.DOUBLE, 0, msgtag); 111 } 112 } 113 } 114 115 116 } 117 118 /** 119 * @param C two-dimensional double array. 120 * @param A two-dimensional double array. 121 * @param B two-dimensional double array. 122 */ 123 public void seqdiff(double[][] C, double[][] A, double[][] B) { 124 for (int i=0; i < C.length; i++) { 125 for (int j=0; j < C[0].length; j++) { 126 C[i][j] = A[i][j] - B[i][j]; 127 } 128 } 129 } 130 131 /** 132 * @param C two-dimensional double array. 133 * @param A two-dimensional double array. 134 * @param B two-dimensional double array. 135 * @param i row of A. 136 * @param j column of B. 137 */ 138 public void dotmult(double[][] C, double[][] A, double[][] B, int i, int j) { 139 double c = 0.0; 140 for (int k=0; k < B.length; k++) { 141 c += A[i][k] * B[k][j]; 142 } 143 C[i][j] = c; 144 } 145 146 /** 147 * @param C two-dimensional double array. 148 * @param A two-dimensional double array. 149 * @param B two-dimensional double array. 150 */ 151 public void seq2mult(double[][] C, double[][] A, double[][] B) { 152 for (int i=0; i < A.length; i++) { 153 for (int j=0; j < B[0].length; j++) { 154 dotmult(C,A,B,i,j); 155 } 156 } 157 } 158 159 /** 160 * @param n rows of result. 161 * @param m columns of result. 162 * @return A. 163 */ 164 public double[][] matgen(int n, int m) { 165 double[][] A = new double[n][m]; 166 for (int i=0; i < n; i++) { 167 for (int j=0; j < m; j++) { 168 A[i][j] = Math.random(); 169 } 170 } 171 return A; 172 } 173 174 /** 175 * @param n rows of result. 176 * @param m columns of result. 177 * @return A. 178 */ 179 public double[][] matgen0(int n, int m) { 180 double[][] A = new double[n][m]; 181 for (int i=0; i < n; i++) { 182 for (int j=0; j < m; j++) { 183 A[i][j] = 0.0; 184 } 185 } 186 return A; 187 } 188 /** 189 * @param n rows of result. 190 * @param m columns of result. 191 * @return A. 192 */ 193 public double[][] matgen1(int n, int m) { 194 double[][] A = new double[n][m]; 195 for (int i=0; i < n; i++) { 196 for (int j=0; j < m; j++) { 197 if (i == j) A[i][j] = 1.0; else A[i][j]= 0.0; 198 } 199 } 200 return A; 201 } 202 203 /** 204 * @param A two-dimensional double array. 205 */ 206 public void matprint(double[][] A) { 207 for (int i=0; i < A.length; i++) { 208 for (int j=0; j < A[0].length; j++) { 209 System.out.print(A[i][j] + " "); 210 } 211 System.out.println(); 212 } 213 } 214 215 /** 216 * @param V vector. 217 */ 218 public void vecprint(int[] V) { 219 for (int i=0; i < V.length; i++) { 220 System.out.print(V[i] + " "); 221 } 222 System.out.println(); 223 } 224 225 /** 226 * @param A two-dimensional double array. 227 * @return true if A is approximately zero. 228 */ 229 public boolean matcheck0(double[][] A) { 230 double eps = Double.MIN_VALUE*1000.0; 231 for (int i=0; i < A.length; i++) { 232 for (int j=0; j < A[0].length; j++) { 233 if ( Math.abs(A[i][j]) > eps) return false; 234 } 235 } 236 return true; 237 } 238 239 public static void main(String[] args) throws MPIException { 240 241 int n = 300, m = 300; 242 boolean prnt = false; 243 244 try { n = Integer.parseInt(args[0]); } 245 catch (Exception e) { } 246 try { m = Integer.parseInt(args[1]); } 247 catch (Exception e) { } 248 try { prnt = Boolean.valueOf(args[2]).booleanValue(); } 249 catch (Exception e) { } 250 251 //prnt=true; 252 253 MPI.Init(args) ; 254 int myid = MPI.COMM_WORLD.Rank() ; 255 256 MatrixMultMPI x = new MatrixMultMPI(); 257 258 double[][] A; 259 double[][] B; 260 double[][] C; 261 double[][] D; 262 long tm =0; 263 264 if ( myid == 0 ) { 265 A = x.matgen1(n,m); 266 B = x.matgen(m,n); 267 C = x.matgen0(n,n); 268 D = x.matgen0(n,n); 269 } else { 270 A = new double[n][m]; 271 B = new double[m][n]; 272 C = new double[n][n]; 273 D = new double[n][n]; 274 } 275 276 if ( myid == 0 ) { 277 System.out.println("A = "); 278 if (prnt) x.matprint(A); 279 System.out.println(""); 280 281 System.out.println("B = "); 282 if (prnt) x.matprint(B); 283 System.out.println(""); 284 285 System.out.println("C = "); 286 tm = System.currentTimeMillis(); 287 x.seqmult(C,A,B); 288 tm = System.currentTimeMillis() - tm; 289 System.out.println(tm + "ms"); 290 } 291 292 tm = System.currentTimeMillis(); 293 x.parmult(C,A,B); 294 tm = System.currentTimeMillis() - tm; 295 296 if ( myid == 0 ) { 297 System.out.println(tm + "ms"); 298 if (prnt) x.matprint(C); 299 System.out.println(""); 300 301 System.out.println("D = "); 302 x.seqdiff(D,B,C); 303 if (prnt) x.matprint(D); 304 System.out.println(""); 305 System.out.println("D is zero = " + x.matcheck0(D) ); 306 } 307 308 MPI.Finalize(); 309 310 } 311 312 }