001 /* 002 * $Id: MatrixMultOmp.jomp,v 1.5 2002/08/03 17:14:31 kredel Exp $ 003 */ 004 005 //package edu.unima.ky.parallel.jomp; 006 007 /** 008 * Matrix Multiplication 009 * sequential and parallel using OpenMP 010 * @author Akitoshi Yoshida 011 * @author Heinz Kredel. 012 */ 013 014 public class MatrixMultOmp { 015 016 017 /** 018 * @param C two-dimensional double array. 019 * @param A two-dimensional double array. 020 * @param B two-dimensional double array. 021 */ 022 public void seqmult(double[][] C, double[][] A, double[][] B) { 023 for (int i=0; i < A.length; i++) { 024 for (int j=0; j < B[0].length; j++) { 025 double c = 0.0; 026 for (int k=0; k < B.length; k++) { 027 c += A[i][k] * B[k][j]; 028 } 029 C[i][j] = c; 030 } 031 } 032 } 033 034 035 /** 036 * @param C two-dimensional double array. 037 * @param A two-dimensional double array. 038 * @param B two-dimensional double array. 039 */ 040 public void parmult(double[][] C, double[][] A, double[][] B) { 041 042 // OMP PARALLEL BLOCK BEGINS 043 { 044 __omp_Class0 __omp_Object0 = new __omp_Class0(); 045 // shared variables 046 __omp_Object0.B = B; 047 __omp_Object0.A = A; 048 __omp_Object0.C = C; 049 // firstprivate variables 050 try { 051 jomp.runtime.OMP.doParallel(__omp_Object0); 052 } catch(Throwable __omp_exception) { 053 System.err.println("OMP Warning: Illegal thread exception ignored!"); 054 System.err.println(__omp_exception); 055 } 056 // reduction variables 057 // shared variables 058 B = __omp_Object0.B; 059 A = __omp_Object0.A; 060 C = __omp_Object0.C; 061 } 062 // OMP PARALLEL BLOCK ENDS 063 064 } 065 066 067 /** 068 * @param C two-dimensional double array. 069 * @param A two-dimensional double array. 070 * @param B two-dimensional double array. 071 */ 072 public void seqdiff(double[][] C, double[][] A, double[][] B) { 073 for (int i=0; i < C.length; i++) { 074 for (int j=0; j < C[0].length; j++) { 075 C[i][j] = A[i][j] - B[i][j]; 076 } 077 } 078 } 079 080 081 /** 082 * @param C two-dimensional double array. 083 * @param A two-dimensional double array. 084 * @param B two-dimensional double array. 085 * @param i row of A. 086 * @param j column of B. 087 */ 088 public void dotmult(double[][] C, double[][] A, double[][] B, int i, int 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 * @param C two-dimensional double array. 099 * @param A two-dimensional double array. 100 * @param B two-dimensional double array. 101 */ 102 public void seq2mult(double[][] C, double[][] A, double[][] B) { 103 for (int i=0; i < A.length; i++) { 104 for (int j=0; j < B[0].length; j++) { 105 dotmult(C,A,B,i,j); 106 } 107 } 108 } 109 110 111 /** 112 * @param n rows of result. 113 * @param m columns of result. 114 * @return A two-dimensional double array. 115 */ 116 public double[][] matgen(int n, int m) { 117 double A[][] = new double[n][m]; 118 for (int i=0; i < n; i++) { 119 for (int j=0; j < m; j++) { 120 A[i][j] = Math.random(); 121 } 122 } 123 return A; 124 } 125 126 127 /** 128 * @param n rows of result. 129 * @param m columns of result. 130 * @return A two-dimensional double array. 131 */ 132 public double[][] matgen0(int n, int m) { 133 double A[][] = new double[n][m]; 134 for (int i=0; i < n; i++) { 135 for (int j=0; j < m; j++) { 136 A[i][j] = 0.0; 137 } 138 } 139 return A; 140 } 141 142 143 /** 144 * @param n rows of result. 145 * @param m columns of result. 146 * @return A two-dimensional double array. 147 */ 148 public double[][] matgen1(int n, int m) { 149 double A[][] = new double[n][m]; 150 for (int i=0; i < n; i++) { 151 for (int j=0; j < m; j++) { 152 if (i == j) A[i][j] = 1.0; else A[i][j]= 0.0; 153 } 154 } 155 return A; 156 } 157 158 159 /** 160 * @param A two-dimensional double array. 161 */ 162 public void matprint(double[][] A) { 163 for (int i=0; i < A.length; i++) { 164 for (int j=0; j < A[0].length; j++) { 165 System.out.print(A[i][j] + " "); 166 } 167 System.out.println(); 168 } 169 } 170 171 172 /** 173 * @param A two-dimensional double array. 174 * @return true if A is approximately zero. 175 */ 176 public boolean matcheck0(double[][] A) { 177 double eps = Double.MIN_VALUE*1000.0; 178 for (int i=0; i < A.length; i++) { 179 for (int j=0; j < A[0].length; j++) { 180 if ( Math.abs(A[i][j]) > eps) return false; 181 } 182 } 183 return true; 184 } 185 186 187 /** 188 */ 189 public static void main(String[] args) { 190 191 int n = 200, m = 400; 192 boolean prnt = false; 193 194 try { n = Integer.parseInt(args[0]); } 195 catch (Exception e) { } 196 try { m = Integer.parseInt(args[1]); } 197 catch (Exception e) { } 198 try { prnt = Boolean.valueOf(args[2]).booleanValue(); } 199 catch (Exception e) { } 200 201 MatrixMultOmp x = new MatrixMultOmp(); 202 203 double[][] A = x.matgen1(n,m); 204 double[][] B = x.matgen(m,n); 205 double[][] C = x.matgen0(n,n); 206 double[][] D = x.matgen0(n,n); 207 208 System.out.println("A = "); 209 if (prnt) x.matprint(A); 210 System.out.println(""); 211 212 System.out.println("B = "); 213 if (prnt) x.matprint(B); 214 System.out.println(""); 215 216 System.out.println("C = "); 217 long tm = System.currentTimeMillis(); 218 x.seqmult(C,A,B); 219 tm = System.currentTimeMillis() - tm; 220 System.out.println(tm + "ms"); 221 //x.seq2mult(C,A,B); 222 tm = System.currentTimeMillis(); 223 x.parmult(C,A,B); 224 tm = System.currentTimeMillis() - tm; 225 System.out.println(tm + "ms"); 226 if (prnt) x.matprint(C); 227 System.out.println(""); 228 229 System.out.println("D = "); 230 x.seqdiff(D,B,C); 231 if (prnt) x.matprint(D); 232 System.out.println(""); 233 System.out.println("D is zero = " + x.matcheck0(D) ); 234 235 } 236 237 // OMP PARALLEL REGION INNER CLASS DEFINITION BEGINS 238 private class __omp_Class0 extends jomp.runtime.BusyTask { 239 // shared variables 240 double [ ] [ ] B; 241 double [ ] [ ] A; 242 double [ ] [ ] C; 243 // firstprivate variables 244 // variables to hold results of reduction 245 246 public void go(int __omp_me) throws Throwable { 247 // firstprivate variables + init 248 // private variables 249 // reduction variables, init to default 250 // OMP USER CODE BEGINS 251 252 { // OMP FOR BLOCK BEGINS 253 // copy of firstprivate variables, initialized 254 // copy of lastprivate variables 255 // variables to hold result of reduction 256 boolean amLast=false; 257 { 258 // firstprivate variables + init 259 // [last]private variables 260 // reduction variables + init to default 261 // ------------------------------------- 262 jomp.runtime.LoopData __omp_WholeData2 = new jomp.runtime.LoopData(); 263 jomp.runtime.LoopData __omp_ChunkData1 = new jomp.runtime.LoopData(); 264 __omp_WholeData2.start = (long)(0); 265 __omp_WholeData2.stop = (long)( A.length); 266 __omp_WholeData2.step = (long)(1); 267 jomp.runtime.OMP.setChunkStatic(__omp_WholeData2); 268 while(!__omp_ChunkData1.isLast && jomp.runtime.OMP.getLoopStatic(__omp_me, __omp_WholeData2, __omp_ChunkData1)) { 269 for(;;) { 270 if(__omp_WholeData2.step > 0) { 271 if(__omp_ChunkData1.stop > __omp_WholeData2.stop) __omp_ChunkData1.stop = __omp_WholeData2.stop; 272 if(__omp_ChunkData1.start >= __omp_WholeData2.stop) break; 273 } else { 274 if(__omp_ChunkData1.stop < __omp_WholeData2.stop) __omp_ChunkData1.stop = __omp_WholeData2.stop; 275 if(__omp_ChunkData1.start > __omp_WholeData2.stop) break; 276 } 277 for(int i = (int)__omp_ChunkData1.start; i < __omp_ChunkData1.stop; i += __omp_ChunkData1.step) { 278 // OMP USER CODE BEGINS 279 { 280 for (int j=0; j < B[0].length; j++) { 281 double c = 0.0; 282 for (int k=0; k < B.length; k++) { 283 c += A[i][k] * B[k][j]; 284 } 285 C[i][j] = c; 286 } 287 } 288 // OMP USER CODE ENDS 289 if (i == (__omp_WholeData2.stop-1)) amLast = true; 290 } // of for 291 if(__omp_ChunkData1.startStep == 0) 292 break; 293 __omp_ChunkData1.start += __omp_ChunkData1.startStep; 294 __omp_ChunkData1.stop += __omp_ChunkData1.startStep; 295 } // of for(;;) 296 } // of while 297 // call reducer 298 jomp.runtime.OMP.doBarrier(__omp_me); 299 // copy lastprivate variables out 300 if (amLast) { 301 } 302 } 303 // set global from lastprivate variables 304 if (amLast) { 305 } 306 // set global from reduction variables 307 if (jomp.runtime.OMP.getThreadNum(__omp_me) == 0) { 308 } 309 } // OMP FOR BLOCK ENDS 310 311 // OMP USER CODE ENDS 312 // call reducer 313 // output to _rd_ copy 314 if (jomp.runtime.OMP.getThreadNum(__omp_me) == 0) { 315 } 316 } 317 } 318 // OMP PARALLEL REGION INNER CLASS DEFINITION ENDS 319 320 } 321