1 public class Convolution extends Thread {
5 public Convolution(Image img, int x0, int x1, int y0, int y1) {
15 int tempx0, tempy0, tempx1, tempy1;
24 //Add manual prefetch this.img.inputImage[] the first 32 objects
25 short[] offsets = new short[6];
26 offsets[0] = getoffset{Convolution, img};
27 offsets[1] = (short) 0;
28 offsets[2] = getoffset{Image, inputImage};
29 offsets[3] = (short) 0;
30 offsets[4] = (short) tempx0;
31 offsets[5] = (short) 31;
32 System.rangePrefetch(this, offsets);
34 //Prefetch this.img.outputImage[] the first 32 objects
35 offsets[2] = getoffset{Image, outputImage};
36 offsets[3] = (short) 0;
37 System.rangePrefetch(this, offsets);
42 double[][] kernel = new double[kernelHeight][kernelWidth];
46 double tempinput[][] = img.inputImage;
47 double tempout[][] = img.outputImage;
49 double tinput1[] = tempinput[x0];
50 double tinput2[] = tempinput[x0+1];
51 double tinput3[] = tempinput[x0+2];
52 double tinput4[] = tempinput[x0+3];
53 double tinput5[] = tempinput[x0+4];
54 double tinput6[] = tempinput[x0+5];
55 double tinput7[] = tempinput[x0+6];
56 double tinput8[] = tempinput[x0+7];
57 double tinput9[] = tempinput[x0+8];
58 double tinput10[] = tempinput[x0+9];
59 double tinput11[] = tempinput[x0+10];
60 double tinput12[] = tempinput[x0+11];
61 double tinput13[] = tempinput[x0+12];
62 double tinput14[] = tempinput[x0+13];
63 double tinput0[] = tinput1;
64 short[] offsets2 = new short[2];
68 for(int i=x0;i<x1;i++,l++){
69 if((i&31) == 0) { //prefetch every 16th iteration
70 //Prefetch this.img.inputImage[]
71 offsets2[0] = (short) (i+32);
72 offsets2[1] = (short) 31;
73 System.rangePrefetch(tempinput, offsets2);
74 System.rangePrefetch(tempout, offsets2);
77 double tout[] = tempout[i];
78 tinput0 = tinput1; tinput1=tinput2; tinput2=tinput3; tinput3=tinput4; tinput4=tinput5;
79 tinput5 = tinput6; tinput6=tinput7; tinput7=tinput8; tinput8=tinput9; tinput9=tinput10;
80 tinput10 = tinput11; tinput11=tinput12; tinput12=tinput13; tinput13=tinput14; tinput14=tempinput[l];
81 for(int j=y0;j<y1;++j){
83 for(int b=0;b<kernelHeight;++b) {
84 s+=(tinput0[j+b] * kernel[0][b] + tinput1[j+b] * kernel[1][b] + tinput2[j+b]*kernel[2][b] +
85 tinput3[j+b]*kernel[3][b] + tinput4[j+b]*kernel[4][b] + tinput5[j+b]*kernel[5][b]+
86 tinput6[j+b]*kernel[6][b] + tinput7[j+b]*kernel[7][b] + tinput8[j+b]*kernel[8][b]+
87 tinput9[j+b]*kernel[9][b] + tinput10[j+b]*kernel[10][b] + tinput11[j+b]*kernel[11][b]+
88 tinput12[j+b]*kernel[12][b]+ tinput13[j+b]*kernel[13][b] + tinput14[j+b]*kernel[14][b]);
96 public static void main(String[] args) {
99 int kernelHeight=15, kernelWidth=15;
102 NUM_THREADS = Integer.parseInt(args[0]);
104 SIZE = Integer.parseInt(args[1]);
108 int[] mid = new int[8];
109 mid[0] = (128<<24)|(195<<16)|(136<<8)|162; //dw-10
110 mid[1] = (128<<24)|(195<<16)|(136<<8)|163; //dw-11
111 mid[2] = (128<<24)|(195<<16)|(136<<8)|164; //dw-12
112 mid[3] = (128<<24)|(195<<16)|(136<<8)|165; //dw-13
113 mid[4] = (128<<24)|(195<<16)|(136<<8)|166; //dw-14
114 mid[5] = (128<<24)|(195<<16)|(136<<8)|167; //dw-15
115 mid[6] = (128<<24)|(195<<16)|(136<<8)|168; //dw-16
116 mid[7] = (128<<24)|(195<<16)|(136<<8)|169; //dw-17
123 img = global new Image(SIZE,SIZE,kernelHeight,kernelWidth);
125 conv = global new Convolution[NUM_THREADS];
126 int increment=SIZE/NUM_THREADS;
128 for(int i = 0; i<NUM_THREADS; i++) {
129 if((i+1)==NUM_THREADS)
130 conv[i] = global new Convolution(img, base, SIZE, 0, SIZE);
132 conv[i] = global new Convolution(img, base, base+increment, 0, SIZE);
139 System.printString("img.outputImage[10][20] = " +(int) img.outputImage[10][20] + "\n");
140 System.printString("img.outputImage[256][890] = " +(int) img.outputImage[256][890] + "\n");
144 System.printString("Convolution: Size=");
145 System.printInt(SIZE);
146 System.printString("\n");
148 for(int i = 0; i <NUM_THREADS; i++) {
155 for(int i = 0; i < NUM_THREADS; i++) {
162 System.printString("2DConv Done!\n");
166 System.printString("img.outputImage[10][20] = " +(int) img.outputImage[10][20] + "\n");
167 System.printString("img.outputImage[256][890] = " +(int) img.outputImage[256][890] + "\n");
172 //define 15X15 Gaussian kernel
173 public static void initKernel15(double[][] kernel) {
174 kernel[0][0] = 1/256.0;
175 kernel[0][1] = 4/256.0;
176 kernel[0][2] = 6/256.0;
177 kernel[0][3] = 8/256.0;
178 kernel[0][4] = 10/256.0;
179 kernel[0][5] = 12/256.0;
180 kernel[0][6] = 14/256.0;
181 kernel[0][7] = 16/256.0;
182 kernel[0][8] = 14/256.0;
183 kernel[0][9] = 12/256.0;
184 kernel[0][10] = 10/256.0;
185 kernel[0][11] = 8/256.0;
186 kernel[0][12] = 6/256.0;
187 kernel[0][13] = 4/256.0;
188 kernel[0][14] = 1/256.0;
190 kernel[1][0] = 4/256.0;
191 kernel[1][1] = 16/256.0;
192 kernel[1][2] = 24/256.0;
193 kernel[1][3] = 32/256.0;
194 kernel[1][4] = 40/256.0;
195 kernel[1][5] = 48/256.0;
196 kernel[1][6] = 56/256.0;
197 kernel[1][7] = 64/256.0;
198 kernel[1][8] = 56/256.0;
199 kernel[1][9] = 48/256.0;
200 kernel[1][10] = 40/256.0;
201 kernel[1][11] = 32/256.0;
202 kernel[1][12] = 24/256.0;
203 kernel[1][13] = 16/256.0;
204 kernel[1][14] = 4/256.0;
206 kernel[2][0] = 6/256.0;
207 kernel[2][1] = 24/256.0;
208 kernel[2][2] = 36/256.0;
209 kernel[2][3] = 48/256.0;
210 kernel[2][4] = 60/256.0;
211 kernel[2][5] = 72/256.0;
212 kernel[2][6] = 84/256.0;
213 kernel[2][7] = 96/256.0;
214 kernel[2][8] = 84/256.0;
215 kernel[2][9] = 72/256.0;
216 kernel[2][10] = 60/256.0;
217 kernel[2][11] = 48/256.0;
218 kernel[2][12] = 36/256.0;
219 kernel[2][13] = 24/256.0;
220 kernel[2][14] = 6/256.0;
222 kernel[3][0] = 8/256.0;
223 kernel[3][1] = 32/256.0;
224 kernel[3][2] = 48/256.0;
225 kernel[3][3] = 64/256.0;
226 kernel[3][4] = 80/256.0;
227 kernel[3][5] = 96/256.0;
228 kernel[3][6] = 112/256.0;
229 kernel[3][7] = 128/256.0;
230 kernel[3][8] = 112/256.0;
231 kernel[3][9] = 96/256.0;
232 kernel[3][10] = 80/256.0;
233 kernel[3][11] = 64/256.0;
234 kernel[3][12] = 48/256.0;
235 kernel[3][13] = 32/256.0;
236 kernel[3][14] = 8/256.0;
239 kernel[4][0] = 10/256.0;
240 kernel[4][1] = 40/256.0;
241 kernel[4][2] = 60/256.0;
242 kernel[4][3] = 80/256.0;
243 kernel[4][4] = 100/256.0;
244 kernel[4][5] = 120/256.0;
245 kernel[4][6] = 140/256.0;
246 kernel[4][7] = 160/256.0;
247 kernel[4][8] = 140/256.0;
248 kernel[4][9] = 120/256.0;
249 kernel[4][10] = 100/256.0;
250 kernel[4][11] = 80/256.0;
251 kernel[4][12] = 60/256.0;
252 kernel[4][13] = 40/256.0;
253 kernel[4][14] = 10/256.0;
255 kernel[5][0] = 12/256.0;
256 kernel[5][1] = 48/256.0;
257 kernel[5][2] = 72/256.0;
258 kernel[5][3] = 96/256.0;
259 kernel[5][4] = 120/256.0;
260 kernel[5][5] = 144/256.0;
261 kernel[5][6] = 168/256.0;
262 kernel[5][7] = 192/256.0;
263 kernel[5][8] = 168/256.0;
264 kernel[5][9] = 144/256.0;
265 kernel[5][10] = 120/256.0;
266 kernel[5][11] = 96/256.0;
267 kernel[5][12] = 72/256.0;
268 kernel[5][13] = 48/256.0;
269 kernel[5][14] = 12/256.0;
271 kernel[6][0] = 14/256.0;
272 kernel[6][1] = 56/256.0;
273 kernel[6][2] = 84/256.0;
274 kernel[6][3] = 112/256.0;
275 kernel[6][4] = 140/256.0;
276 kernel[6][5] = 168/256.0;
277 kernel[6][6] = 196/256.0;
278 kernel[6][7] = 224/256.0;
279 kernel[6][8] = 196/256.0;
280 kernel[6][9] = 168/256.0;
281 kernel[6][10] = 140/256.0;
282 kernel[6][11] = 112/256.0;
283 kernel[6][12] = 84/256.0;
284 kernel[6][13] = 56/256.0;
285 kernel[6][14] = 14/256.0;
287 kernel[7][0] = 16/256.0;
288 kernel[7][1] = 64/256.0;
289 kernel[7][2] = 96/256.0;
290 kernel[7][3] = 128/256.0;
291 kernel[7][4] = 160/256.0;
292 kernel[7][5] = 192/256.0;
293 kernel[7][6] = 224/256.0;
294 kernel[7][7] = 256/256.0;
295 kernel[7][8] = 224/256.0;
296 kernel[7][9] = 192/256.0;
297 kernel[7][10] = 160/256.0;
298 kernel[7][11] = 128/256.0;
299 kernel[7][12] = 96/256.0;
300 kernel[7][13] = 64/256.0;
301 kernel[7][14] = 16/256.0;
303 kernel[8][0] = 14/256.0;
304 kernel[8][1] = 56/256.0;
305 kernel[8][2] = 84/256.0;
306 kernel[8][3] = 112/256.0;
307 kernel[8][4] = 140/256.0;
308 kernel[8][5] = 168/256.0;
309 kernel[8][6] = 196/256.0;
310 kernel[8][7] = 224/256.0;
311 kernel[8][8] = 196/256.0;
312 kernel[8][9] = 168/256.0;
313 kernel[8][10] = 140/256.0;
314 kernel[8][11] = 112/256.0;
315 kernel[8][12] = 84/256.0;
316 kernel[8][13] = 56/256.0;
317 kernel[8][14] = 14/256.0;
319 kernel[9][0] = 12/256.0;
320 kernel[9][1] = 48/256.0;
321 kernel[9][2] = 72/256.0;
322 kernel[9][3] = 96/256.0;
323 kernel[9][4] = 120/256.0;
324 kernel[9][5] = 144/256.0;
325 kernel[9][6] = 168/256.0;
326 kernel[9][7] = 192/256.0;
327 kernel[9][8] = 168/256.0;
328 kernel[9][9] = 144/256.0;
329 kernel[9][10] = 120/256.0;
330 kernel[9][11] = 96/256.0;
331 kernel[9][12] = 72/256.0;
332 kernel[9][13] = 48/256.0;
333 kernel[9][14] = 12/256.0;
335 kernel[10][0] = 10/256.0;
336 kernel[10][1] = 40/256.0;
337 kernel[10][2] = 60/256.0;
338 kernel[10][3] = 80/256.0;
339 kernel[10][4] = 100/256.0;
340 kernel[10][5] = 120/256.0;
341 kernel[10][6] = 140/256.0;
342 kernel[10][7] = 160/256.0;
343 kernel[10][8] = 140/256.0;
344 kernel[10][9] = 120/256.0;
345 kernel[10][10] = 100/256.0;
346 kernel[10][11] = 80/256.0;
347 kernel[10][12] = 60/256.0;
348 kernel[10][13] = 40/256.0;
349 kernel[10][14] = 10/256.0;
351 kernel[11][0] = 8/256.0;
352 kernel[11][1] = 32/256.0;
353 kernel[11][2] = 48/256.0;
354 kernel[11][3] = 64/256.0;
355 kernel[11][4] = 80/256.0;
356 kernel[11][5] = 96/256.0;
357 kernel[11][6] = 112/256.0;
358 kernel[11][7] = 128/256.0;
359 kernel[11][8] = 112/256.0;
360 kernel[11][9] = 96/256.0;
361 kernel[11][10] = 80/256.0;
362 kernel[11][11] = 64/256.0;
363 kernel[11][12] = 48/256.0;
364 kernel[11][13] = 32/256.0;
365 kernel[11][14] = 8/256.0;
367 kernel[12][0] = 6/256.0;
368 kernel[12][1] = 24/256.0;
369 kernel[12][2] = 36/256.0;
370 kernel[12][3] = 48/256.0;
371 kernel[12][4] = 60/256.0;
372 kernel[12][5] = 72/256.0;
373 kernel[12][6] = 84/256.0;
374 kernel[12][7] = 96/256.0;
375 kernel[12][8] = 84/256.0;
376 kernel[12][9] = 72/256.0;
377 kernel[12][10] = 60/256.0;
378 kernel[12][11] = 48/256.0;
379 kernel[12][12] = 36/256.0;
380 kernel[12][13] = 24/256.0;
381 kernel[12][14] = 6/256.0;
383 kernel[13][0] = 4/256.0;
384 kernel[13][1] = 16/256.0;
385 kernel[13][2] = 24/256.0;
386 kernel[13][3] = 32/256.0;
387 kernel[13][4] = 40/256.0;
388 kernel[13][5] = 48/256.0;
389 kernel[13][6] = 56/256.0;
390 kernel[13][7] = 64/256.0;
391 kernel[13][8] = 56/256.0;
392 kernel[13][9] = 48/256.0;
393 kernel[13][10] = 40/256.0;
394 kernel[13][11] = 32/256.0;
395 kernel[13][12] = 24/256.0;
396 kernel[13][13] = 16/256.0;
397 kernel[13][14] = 4/256.0;
399 kernel[14][0] = 1/256.0;
400 kernel[14][1] = 4/256.0;
401 kernel[14][2] = 6/256.0;
402 kernel[14][3] = 8/256.0;
403 kernel[14][4] = 10/256.0;
404 kernel[14][5] = 12/256.0;
405 kernel[14][6] = 14/256.0;
406 kernel[14][7] = 16/256.0;
407 kernel[14][8] = 14/256.0;
408 kernel[14][9] = 12/256.0;
409 kernel[14][10] = 10/256.0;
410 kernel[14][11] = 8/256.0;
411 kernel[14][12] = 6/256.0;
412 kernel[14][13] = 4/256.0;
413 kernel[14][14] = 1/256.0;
419 int kernelWidth, kernelHeight;
420 double[][] inputImage;
421 double[][] outputImage;
423 public Image(int width, int height, int kernelWidth, int kernelHeight) {
425 this.height = height;
426 this.kernelWidth = kernelWidth;
427 this.kernelHeight = kernelHeight;
428 inputImage = global new double[height+kernelHeight-1][width+kernelWidth-1];
429 outputImage = global new double[height][width];
432 /* Create a valid image */
433 public void setValues() {
434 for (int i = 0; i < (height+kernelHeight - 1); i++) {
435 double ainput[] = inputImage[i];
436 for(int j = 0; j < (width+kernelWidth - 1); j++) {
441 for (int i = 0; i < height; i++){
442 double aout[] = outputImage[i];
443 for(int j = 0; j < width; j++) {