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