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